Waaah, I don't get paid to use new shiny languages


  • Banned

    @error but why would you ever want to set something to undefined in the first place?

    Everyone hates C++ because it's too confusing. But JS devs make me think they hate C++ because it's not confusing enough.



  • @izzion said in Waaah, I don't get paid to use new shiny languages:

    @Mason_Wheeler
    I'm not arguing it's not an improvement. Just that it's still (functionally, logically, and effectively) a null, and if you want to argue that a language "doesn't have nulls" because it uses the Option/None pattern instead, then I'm going to lampoon you.

    So basically Nullable<T>.

    It's odd to me that an enum value can also contain a value. I wonder if that complicates things, like where certain features require a const value.



  • @Gąska If you're going to blather on about mathematical types, the least you could do is call null by its proper name: Unit. Also, you really should read @Mason_Wheeler's link: Midori is an experimental Microsoft operating system written in a C# derivative which a) has non-nullability by default, and b) lets you specify arbitrary constraints that are checked at compile time and form part of the function signature -- essentially, the same constraints you want, but expressed not as types, but expressions. And they ported most of Windows' server stack to it, including IIS/ASP.NET, Speech Services, and Media Services.


  • BINNED

    @TwelveBaud said in Waaah, I don't get paid to use new shiny languages:

    @Gąska If you're going to blather on about mathematical types, the least you could do is call null by its proper name: Unit.

    In type theory it's called the bottom type, but in programming languages it usually has a more useful name. E.g. Scala has Nothing, TypeScript has never, and Rust has ! (don't ask).

    I think he’s shown there’s more than one “proper name”.


  • Banned

    @xaade said in Waaah, I don't get paid to use new shiny languages:

    It's odd to me that an enum value can also contain a value.

    "Enum" is a misnomer. They're properly called variant types. The Option type has two variants, one is zero-argument None, the other is one-argument Some.

    It's just that a variant type with multiple zero-argument variants looks very similar to an enumerated type, so people who do both normal and functional programming started using the terms interchangeably. Also tagged union, which originates from C programmers thinking they are being so innovative with making a union of structs and dedicating the first field to a type tag.

    That's what happens when people forget that words have meaning.



  • @Gąska Yeah, it's long, and not all of it is relevant to the topic of checked exceptions. It's worth reading though.

    Brief overview of the salient points. First, this comparison

    c7b0151e-60a3-4358-917a-740f77aad7a0-image.png

    Second, bugs are not recoverable errors. Anything that is a programming error (null dereference, array out of bounds, division by zero, etc) has no good way to recover, so don't even try. Generate an error report for the developer, then fail-fast and trash the entire process. (There's a big long digression about how the painful effects of this can be mitigated by using small, isolated processes a la Erlang.) Treating bugs as instant death conditions eliminates about 90% of all cases where exceptions would get thrown in most languages.

    Third, improve the type system by doing things such as putting nullability/non-null into the core type system to eliminate null reference errors (which we've discussed extensively already in this thread) and adding slices to eliminate (or at least greatly reduce) array bounds errors.

    Fourth, set up a checked exceptions system for recoverable errors only. The exceptions that get thrown are treated as a part of the method's signature, so any method that is not marked as throws can not throw any exception.

    At this point, the issue of substitutability is quite simple. A throws function cannot take the place of a non-throws function (illegal strengthening). A non-throws function, on the other hand, can take the place of a throws function (legal weakening). This obviously impacts virtual overrides, interface implementation, and lambdas.

    Of course, we did the expected co- and contravariance substitution bells and whistles. For example, if Foo were virtual and you overrode it but didn’t throw exceptions, you didn’t need to state the throws contract. Anybody invoking such a function virtually, of course, couldn’t leverage this but direct calls could.

    90% of what used to be exceptions are errors and not exceptions, and 90% of remaining methods that do throw anything only throw one exception type, which greatly cuts down on the "checked exception cancer" that is so painful in Java, making things much more tolerable.

    Fifth, make exceptions auditable. If the function Foo is marked as throws, it's a compile-time error to say value = Foo(). Instead, you say value = try Foo(), which makes calls to code that can throw stand out visually. (Particularly in an IDE with syntax highlighting.) Any try{} block with no try method calls in it can be trivially shown to be unnecessary and reported as a warning or elided altogether by the compiler.

    Sixth, have a mechanism for dealing with things that might ordinarily look like a bug but are actually an expected failure possibility, such a out-of-memory when allocating a large buffer, so that they won't trigger abandonment.

    Seventh, add effects typing into the generic constraints system so that throws information can be propagated into generic methods such as LINQ functions without having to rewrite everything twice with a throws and non-throws version.

    (Yes, that long summary is the TLDR version. It's a big article.)


  • Banned

    @TwelveBaud said in Waaah, I don't get paid to use new shiny languages:

    @Gąska If you're going to blather on about mathematical types, the least you could do is call null by its proper name: Unit.

    Unit is unit. It's a proper type with a single value that doesn't belong in any other type. You can't put () where a string is expected. Completely different thing. The distinguishing quality of null value is that it belongs to every class type, past, present and future.

    If you're going to complain about my mathematical blathering, at least get your facts straight.

    Also, you really should read @Mason_Wheeler's link

    I have no reason to believe your assessment of that article is any better than your understanding of unit types. I asked one very specific question, and instead of an answer I've got a link to a 79-page article that's mostly about stuff I didn't ask about. Thanks but no thanks.



  • @Gąska

    This is where it gets philosophical IMO.

    If I understand it correctly, then the language does not have a null equivalent. It's just that you can leverage the more generic concept of a variant type to produce Nullable<T> like functionality.

    If you count patterns as part of the language definition, then C# has a FactoryFactory and a Singleton.


  • Banned

    @xaade the thing about Nullable<T> is that T is itself non-nullable. The essential part of what makes classic null so bad - subtyping every other type automatically while violating their contracts - is not there. null in context of Nullable<T> is much closer to the Option variant type in other languages than to null in context of class types, even though it's the same keyword in the same language with the same functionality.


  • Banned

    @Mason_Wheeler that's cool and all, but it looks like forgetting what the question was. For reference, I ask what you would change in the Java's implementation of checked exceptions. You didn't really answer that.

    Second, bugs are not recoverable errors.

    Yes, and Java already has it covered. Non-recoverable errors - in particular null reference and array out of bounds errors - are derived from RuntimeException and are specifically excluded from the checked exception mechanism. I mean, there are plenty of 3rd party libraries that fuck this up, but the mechanism itself does do the distinction.

    Third, improve the type system by doing things such as putting nullability/non-null into the core type system to eliminate null reference errors (which we've discussed extensively already in this thread) and adding slices to eliminate (or at least greatly reduce) array bounds errors.

    Good idea, but it doesn't impact the mechanism of checked exceptions in any way.

    Fourth, set up a checked exceptions system for recoverable errors only.

    See above. Java already does that.

    Fifth, make exceptions auditable. If the function Foo is marked as throws, it's a compile-time error to say value = Foo(). Instead, you say value = try Foo(), which makes calls to code that can throw stand out visually.

    A very minor detail that boils down to mandatory syntactical boilerplate (the good kind, but still), and doesn't change at all how checked exceptions behave on the semantic level.

    Sixth, have a mechanism for dealing with things that might ordinarily look like a bug but are actually an expected failure possibility, such a out-of-memory when allocating a large buffer, so that they won't trigger abandonment.

    This isn't related to checked exceptions. OoM and similar are already unchecked in Java.

    Seventh, add effects typing into the generic constraints system so that throws information can be propagated into generic methods such as LINQ functions without having to rewrite everything twice with a throws and non-throws version.

    Considering that checked exceptions were deemed a failure before Java even had generics, I'm going to count this as irrelevant too, if you allow. Or at most a minor footnote after everything else.


    All in all, I still don't see what you'd change about checked exceptions compared to how they're done in Java.



  • @Gąska I did answer that. I said, read this article, the answer's in there. You asked for a summary of the article, and I gave one. If some specific detail you're looking for isn't in the summary, read the article.


  • Banned

    @Mason_Wheeler said in Waaah, I don't get paid to use new shiny languages:

    @Gąska I did answer that. I said, read this article, the answer's in there.

    You could've as well said "google it up". There's not much practical difference between "somewhere in those 79 pages" and "somewhere on the internet, I don't know where".

    You asked for a summary of the article, and I gave one. If some specific detail you're looking for isn't in the summary, read the article.

    It's not the details. The entire topic is missing from the summary. If that topic is missing in summary, it's extremely unlikely the article contains it either. In case you forgot, my original question was what you'd change in Java's implementation of checked exceptions. The articles goes very deep into all subjects BUT the one I'm interested in.



  • @Gąska said in Waaah, I don't get paid to use new shiny languages:

    I don't even know what Midori is, let alone plan to ever use it in future.

    https://www.youtube.com/watch?v=UUkGdxozd7Y


  • Banned

    @Mason_Wheeler I mean, I'd be more willing to read it if there was some way to hold you accountable to your words. You say it's there, but what if you're wrong? I'm losing huge amount of time, and there's a big risk of me gaining nothing. The article is almost 20000 words. A quick reading speed test I just took indicates I can read 190 words per minute. Going through that article would take me almost two hours, assuming I can keep focused all the time. Which I can't. So realistically it's more like three. Three hours of potentially wasted time. And all I have is your pinky promise.

    Oooooooor, since you've already read it, and you know for sure what's in it, you presumably also know in which part of the article talks about which topics. So I figure you could point me to a specific part of the article that contains the answer to my one very specific question. It costs you nothing, and you'd be saving me hours.



  • @Gąska said in Waaah, I don't get paid to use new shiny languages:

    Oooooooor, since you've already read it, and you know for sure what's in it, you presumably also know in which part of the article talks about which topics. So I figure you could point me to a specific part of the article that contains the answer to my one very specific question. It costs you nothing, and you'd be saving me hours.

    Look at the section titled "Recoverable Errors: Type-Directed Exceptions" for the part that's specifically about the checked exception model.


  • Banned

    @Mason_Wheeler thanks. I'll read it and get back to you.


  • Banned

    @Mason_Wheeler that's not a section, that's a fucking 20-page chapter with a dozen sub-headers.

    You know what, nevermind. It's blatantly clear you're not interested in me getting any wiser, and I'm not interested in roasting you anymore either.


  • ♿ (Parody)

    @Gąska said in Waaah, I don't get paid to use new shiny languages:

    For reference, I ask what you would change in the Java's implementation of checked exceptions.

    There's not a succinct thing, but being someone who uses Java daily I read through it. The biggest thing (outside of the RuntimeException issue vs his preferred "abandonment" approach) was that try blocks were sloppy in that they'd often be put around big blocks of code and so the handling of exceptions and the way the code would work with them was pretty unreliable and probably often wrong.

    @Mason_Wheeler kind of touched on that in his summary when he mentioned value = try Foo(), but didn't bring up that point from TFA.

    His issues with Java didn't really have too much to do with the checked aspect of exceptions (aside from not seeing any indication where a method is called that it throws).

    Result<int> value = try Foo() else catch;
    if (value.IsFailure) {
        Log(value.Exception);
        throw value.Exception;
    }
    // Use the value `value.Value`..
    
    int value1 = try Foo() else 42;
    int value2 = try Foo() else Release.Fail();
    

    So it looks like he uses these Result things somewhat similarly to your Optional stuff. But, again, the significance to checked stuff is that it exception handling becomes part of the call.



  • @Gąska said in Waaah, I don't get paid to use new shiny languages:

    @Mason_Wheeler that's not a section, that's a fucking 20-page chapter with a dozen sub-headers.

    You know what, nevermind. It's blatantly clear you're not interested in me getting any wiser, and I'm not interested in roasting you anymore either.

    It's not a small or simple topic!


  • Banned

    @Mason_Wheeler CHANGE. What you would CHANGE. Not WHY. Just WHAT. The changes themselves. Without rationale. Just a list of changes themselves. Is your wishlist for changes to Java's exception model really 20 pages long? Sure, yeah, why not. I'd totally read 20 pages of changes - that actually sounds interesting. But only as a LIST. Not as an article. A LIST.


  • Considered Harmful

    @Gąska said in Waaah, I don't get paid to use new shiny languages:

    @error but why would you ever want to set something to undefined in the first place?

    Maybe you wouldn't (I might), but imagine, since you've correctly pointed out the possibility, that you're not aware the variable you're passing is undefined... Except here, that's not technically always wrong - there is an overload that takes no parameters... but that wasn't the caller's intent. They did bind that parameter, they wanted the one parameter overload, they just happened to pass an empty one. Treating them the same is wrong.

    Everyone hates C++ because it's too confusing. But JS devs make me think they hate C++ because it's not confusing enough.

    Fair.


  • :belt_onion:

    @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    weakly[sic]

    :um-pendant: again (I guess I'm in that mood)....

    said:

    Sic is a Latin term meaning “thus.” It is used to indicate that something incorrectly written is intentionally being left as it was in the original. Sic is usually italicized and always surrounded by brackets to indicate that it was not part of the original. Place [sic] right after the error.

    Only use [sic] if you retained the error, not if you corrected it.

    yeah I know...


  • :belt_onion:

    @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    .length is a built-in method to all strings with a specific guarantee. It does not return null.

    I actually agree with you, but I'm going to :um-pendant: you because there's all kinds of fun things you can tamper with like prototypes and own properties to invalidate this contract.

    You'd be crazy to do it, but... You could slap a length property on a string or array, or even replace String.prototype.length or Array.prototype.length, not to mention you could trick the duck typing by passing an object that is merely Array**-like** that doesn't conform to the same contract. Oh, and object Proxies are a thing.

    Yeah, I'm... ignoring the "you've broken the language" case here, because if you've broken the language you're an idiot



  • @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    .length is a built-in method to all strings with a specific guarantee. It does not return null.

    I actually agree with you, but I'm going to :um-pendant: you because there's all kinds of fun things you can tamper with like prototypes and own properties to invalidate this contract.

    You'd be crazy to do it, but... You could slap a length property on a string or array, or even replace String.prototype.length or Array.prototype.length, not to mention you could trick the duck typing by passing an object that is merely Array**-like** that doesn't conform to the same contract. Oh, and object Proxies are a thing.

    "Hey if I use this feature as a footgun it shoots myself in the foot! The language sucks! Never mind that there's no reason to do that except to shoot myself in the foot, that's irrelevant."


  • Banned

    This post is deleted!

  • Banned

    @coderpatsy said in Waaah, I don't get paid to use new shiny languages:

    @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    .length is a built-in method to all strings with a specific guarantee. It does not return null.

    I actually agree with you, but I'm going to :um-pendant: you because there's all kinds of fun things you can tamper with like prototypes and own properties to invalidate this contract.

    You'd be crazy to do it, but... You could slap a length property on a string or array, or even replace String.prototype.length or Array.prototype.length, not to mention you could trick the duck typing by passing an object that is merely Array**-like** that doesn't conform to the same contract. Oh, and object Proxies are a thing.

    "Hey if I use this feature as a footgun it shoots myself in the foot! The language sucks! Never mind that there's no reason to do that except to shoot myself in the foot, that's irrelevant."

    Shooting yourself is one thing. I'm more concerned with library devs shooting me!



  • @Gąska said in Waaah, I don't get paid to use new shiny languages:

    @coderpatsy said in Waaah, I don't get paid to use new shiny languages:

    @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    .length is a built-in method to all strings with a specific guarantee. It does not return null.

    I actually agree with you, but I'm going to :um-pendant: you because there's all kinds of fun things you can tamper with like prototypes and own properties to invalidate this contract.

    You'd be crazy to do it, but... You could slap a length property on a string or array, or even replace String.prototype.length or Array.prototype.length, not to mention you could trick the duck typing by passing an object that is merely Array**-like** that doesn't conform to the same contract. Oh, and object Proxies are a thing.

    "Hey if I use this feature as a footgun it shoots myself in the foot! The language sucks! Never mind that there's no reason to do that except to shoot myself in the foot, that's irrelevant."

    Shooting yourself is one thing. I'm more concerned with library devs shooting me!

    Have you tried saying "hands up, don't shoot!" ❓ :tro-pop:


  • Banned

    @Mason_Wheeler using obscure languages that are very hard to learn works too :trollface:



  • @Gąska Exactly right. Null the single unique "proto"-value in the bottom type. It's just called bottom (or contradiction) if you want to be all math jargony about it. It doesn't even satisfy equality.


  • Banned

    @Captain isn't the mathematical bottom type always empty, though? It certainly doesn't make sense for a contradiction type to be non-empty. On the other hand, it wouldn't be the first time a mathematical term doesn't make sense.


  • Considered Harmful

    @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    .length is a built-in method to all strings with a specific guarantee. It does not return null.

    I actually agree with you, but I'm going to :um-pendant: you because there's all kinds of fun things you can tamper with like prototypes and own properties to invalidate this contract.

    You'd be crazy to do it, but... You could slap a length property on a string or array, or even replace String.prototype.length or Array.prototype.length, not to mention you could trick the duck typing by passing an object that is merely Array**-like** that doesn't conform to the same contract. Oh, and object Proxies are a thing.

    I want to add that, while you might be thinking "those are some pretty far fetched and contrived examples, who would ever do that?" JS is often run client-side, which means it's wide open for anyone to inspect, modify, and manipulate. I do this all the time when I'm setting up my browser extension to save content (definitely not not porn) from sites that are trying to prevent me from doing so. I'll replace functions that call authentication APIs with stubs that return true. If they're validating an array of arguments, and then using them after verifying them, I'll pass in a special proxy that returns a completely different data set the second time it's enumerated.

    For one site, I actually used an AST parser and rewrote significant chunks of their JS before it ran.

    The fun never ends with JS.

    Edit: :hanzo:


  • Considered Harmful

    @coderpatsy said in Waaah, I don't get paid to use new shiny languages:

    @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    .length is a built-in method to all strings with a specific guarantee. It does not return null.

    I actually agree with you, but I'm going to :um-pendant: you because there's all kinds of fun things you can tamper with like prototypes and own properties to invalidate this contract.

    You'd be crazy to do it, but... You could slap a length property on a string or array, or even replace String.prototype.length or Array.prototype.length, not to mention you could trick the duck typing by passing an object that is merely Array**-like** that doesn't conform to the same contract. Oh, and object Proxies are a thing.

    "Hey if I use this feature as a footgun it shoots myself in the foot! The language sucks! Never mind that there's no reason to do that except to shoot myself in the foot, that's irrelevant."

    Except it's actually my preferred language.



  • @error That sounds like a personal problem. 🤪



  • @error Oh I wasn't speaking ill of any language. Just poking fun at the tendency for people to call a language bad because someone misused a feature in a way no sane program would use.

    JS/TS has enough faults already, One doesn't need to go monkeying with the builtin prototypes to :wtf:



  • @Gąska said in Waaah, I don't get paid to use new shiny languages:

    @Captain isn't the mathematical bottom type always empty, though? It certainly doesn't make sense for a contradiction type to be non-empty. On the other hand, it wouldn't be the first time a mathematical term doesn't make sense.

    This is where it gets weird, and why I called null a "proto-value". Values are things you can quantify over, using the universal and existential quantifiers. OK. But in the first order classical logic, a value x always satisfies x = x, which null does not.

    So how you want to encode all this stuff mathematically is somewhat irrelevant, aside from the fact that bottom (the proto-value) is in every type, vacuously, because it doesn't even exist as a value. It is like how the empty set is a subset of every set, because there is nothing in the empty set to be a counter-example. (Maybe this example was your intuition?)

    This is going to be true in every Turing complete language -- there are objects you can create but can not compare, even in principle, because, for example, their evaluation might not terminate. The only way you can avoid having a bottom value is by having a total language, which means the language is strictly weaker than a Turing machine (it's a FSM, basically).


  • Banned

    @Captain I think you're confusing several concepts here. Namely: null, NaN, and actual bottom type (never/Nothing/!). It's NaN that's not equal to itself, not null. It's never that has no values, not null. In all languages I know, null (if the language has it) is a first-class value that can be quantified, can be compared with itself and other values, and is actually equal to itself.

    And the part about being a subtype of every class type isn't vacuous at all. It's a very real phenomenon that has a lot of practical implications, mostly in form of buggy code produced by lazy developers.



  • @Gąska said in Waaah, I don't get paid to use new shiny languages:

    @Mason_Wheeler said in Waaah, I don't get paid to use new shiny languages:

    @topspin said in Waaah, I don't get paid to use new shiny languages:

    @dkf said in Waaah, I don't get paid to use new shiny languages:

    @boomzilla said in Waaah, I don't get paid to use new shiny languages:

    @NeighborhoodButcher said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    I just see no need for enforced no-nullness across a language.

    Ok, but you also need to realize that's a subjective feeling - if you don't see a need for something, it doesn't mean there is no need.

    I'm looking forward to when they reinvent checked exceptions. Their structured error types are almost there, except for the need to explicitly handle things everywhere…

    I always was of the opinion that checked exceptions where the correct idea. One of the worst things about C++ exceptions is that the function signature doesn't tell you about it (you have noexcept now because the previous throws specifier was an abomination).
    Except for OOM exceptions, which can theoretically appear almost anywhere and practically are not existent because Linux shoots you in the head instead of allowing you to have a correct program, I'd like to know what a function can throw.

    But the people who actually have experience with Java all said it's horrible.

    Checked exceptions are a pretty good idea. Java's implementation of it is horrible, and because that's the only place most people know about checked exceptions from, they end up thinking "checked exceptions are horrible."

    How would you change checked exceptions from Java's implementation of them, without compromising their main objective?

    The try/catch syntax is the main culprit.

    What we need(ed) is a better and more convenient way to specify handling vs. propagation.

    At the very minimum, something that would convert exception to another (logic-specific) exception, to some default value or maybe even control statement (short-cut return). It's still not ideal, but easily implementable in 1992 when it was relevant.

    Configuration readCfg(String path) throws InvalidConfiguration {
       var f = new FileInputStream(path) catch as return defaultConfiguration();
     ...
       int magAge = Integer.parseInt(magAgeStr) catch as InvalidConfiguration("non-number magAge in configuration file: "+maxAgeStr);
    ...
    }
    

    Now the real deal: make this handling a proper value, so that it can be passed as an argument and (more importantly) stored in class or closure (which is class property in Java, anyway). Now that is something that is not possible without big overhaul of the language...

    var systemParser = new ConfigurationParser((catch (IOException) as InvalidSystemConfiguration);
    try {
    var systemCfg = parser1.readCfg("main.ini");   //throws InvalidSystemConfiguration, we need to catch it
    } catch (InvalidSystemConfiguration e) {
       //some loud complain to user's face or something
    }
    
    var localCfgParser = new ConfigurationParser( (catch IOException as return Optional.none());
    //no exception thrown! no try/catch needed!
    var magAge = localCfg.readCfg(userName+".ini").map(c->c.getMaxAge()).orElse(systemCfg.getMaxAge());
    

    Edit: This is my take; I have no idea what would other people imagine. Also, I should probably refine the idea - but I have some actual work to do :-)


  • :belt_onion:

    @error said in Waaah, I don't get paid to use new shiny languages:

    For one site, I actually used an AST parser and rewrote significant chunks of their JS before it ran.

    That's... horrifying.


  • BINNED

    @error said in Waaah, I don't get paid to use new shiny languages:

    @error said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    .length is a built-in method to all strings with a specific guarantee. It does not return null.

    I actually agree with you, but I'm going to :um-pendant: you because there's all kinds of fun things you can tamper with like prototypes and own properties to invalidate this contract.

    You'd be crazy to do it, but... You could slap a length property on a string or array, or even replace String.prototype.length or Array.prototype.length, not to mention you could trick the duck typing by passing an object that is merely Array**-like** that doesn't conform to the same contract. Oh, and object Proxies are a thing.

    I want to add that, while you might be thinking "those are some pretty far fetched and contrived examples, who would ever do that?" JS is often run client-side, which means it's wide open for anyone to inspect, modify, and manipulate. I do this all the time when I'm setting up my browser extension to save content (definitely not not porn) from sites that are trying to prevent me from doing so. I'll replace functions that call authentication APIs with stubs that return true. If they're validating an array of arguments, and then using them after verifying them, I'll pass in a special proxy that returns a completely different data set the second time it's enumerated.

    For one site, I actually used an AST parser and rewrote significant chunks of their JS before it ran.

    The fun never ends with JS.

    That's a client side problem more than a JS problem, though. I've done that with Java and x86 assembly.


  • BINNED

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    @error said in Waaah, I don't get paid to use new shiny languages:

    For one site, I actually used an AST parser and rewrote significant chunks of their JS before it ran.

    That's... horrifying.

    Pretty cool if you ask me.
    I don't know much about GreaseMonkey scripts (there seem to be surprisingly few good introductions) but the one or two sites I cobbled something together that needed to change existing things instead of just adding more, I did something pretty fragile with string replacing. Should probably ask how to do it better, but that's for a different thread (and time when I actually care).


  • Discourse touched me in a no-no place

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    Yeah, I'm... ignoring the "you've broken the language" case here, because if you've broken the language you're an idiot

    JS is already and always broken.


  • :belt_onion:

    @topspin said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    @error said in Waaah, I don't get paid to use new shiny languages:

    For one site, I actually used an AST parser and rewrote significant chunks of their JS before it ran.

    That's... horrifying.

    Pretty cool if you ask me.
    I don't know much about GreaseMonkey scripts (there seem to be surprisingly few good introductions) but the one or two sites I cobbled something together that needed to change existing things instead of just adding more, I did something pretty fragile with string replacing. Should probably ask how to do it better, but that's for a different thread (and time when I actually care).

    Horrifying in the super-cool way


  • Discourse touched me in a no-no place

    @Kamil-Podlesak said in Waaah, I don't get paid to use new shiny languages:

    What we need(ed) is a better and more convenient way to specify handling vs. propagation.

    I'm not all that convinced by the examples you followed that up with. 😆 It's an area that it's surprisingly tricky to get right; “obvious” improvements fall apart when dealing with the reality of processing the complexity that comes with real error patterns.



  • @dkf said in Waaah, I don't get paid to use new shiny languages:

    @Kamil-Podlesak said in Waaah, I don't get paid to use new shiny languages:

    What we need(ed) is a better and more convenient way to specify handling vs. propagation.

    I'm not all that convinced by the examples you followed that up with. 😆 It's an area that it's surprisingly tricky to get right; “obvious” improvements fall apart when dealing with the reality of processing the complexity that comes with real error patterns.

    Yes, of course. It is possible in general, as shown by Haskell and other relatively modern functional languages. The question is: is it possible in language like Java, with C-based syntax, and without ever touching the word "monad"? 🤔


  • Discourse touched me in a no-no place

    @Kamil-Podlesak said in Waaah, I don't get paid to use new shiny languages:

    The question is: is it possible in language like Java, with C-based syntax, and without ever touching the word "monad"? 🤔

    Monads? That's really just implementing the default behaviour of exceptions: pass them on out instead of executing the next statement.



  • @dkf said in Waaah, I don't get paid to use new shiny languages:

    @Kamil-Podlesak said in Waaah, I don't get paid to use new shiny languages:

    The question is: is it possible in language like Java, with C-based syntax, and without ever touching the word "monad"? 🤔

    Monads? That's really just implementing the default behaviour of exceptions: pass them on out instead of executing the next statement.

    That this is just one possibility out of... infinite ones, as long as I can implement my own.
    Point is that I would do it just once, in a generic way, and use it at N places. Right now I need to write N try/catch blocks or throws declarations, which is a major PITA, so nobody does that.

    What's worse: this led to situation when everyone resigned and just use non-checked exception. Which is mostly fine... as long as people actually care about using specific ones. But some people just throw up the most generic thing they ca.

    Actually, this just happened to me today, so I am in a ranty mood. Embedded database query failed:

    throw new RuntimeException("relation operator is not allowed inside group operator")
    

    So, how TF am I supposed to handle that...

    But this is off-topic, just a small daily :wtf: :whistling:


  • BINNED

    @Kamil-Podlesak said in Waaah, I don't get paid to use new shiny languages:

    So, how TF am I supposed to handle that...

    Show a message box to the user?


  • Discourse touched me in a no-no place

    @topspin said in Waaah, I don't get paid to use new shiny languages:

    @Kamil-Podlesak said in Waaah, I don't get paid to use new shiny languages:

    So, how TF am I supposed to handle that...

    Show a message box to the user?

    Or delete their home directory. Either way works.



  • @topspin said in Waaah, I don't get paid to use new shiny languages:

    @sloosecannon said in Waaah, I don't get paid to use new shiny languages:

    @error said in Waaah, I don't get paid to use new shiny languages:

    For one site, I actually used an AST parser and rewrote significant chunks of their JS before it ran.

    That's... horrifying.

    Pretty cool if you ask me.
    I don't know much about GreaseMonkey scripts (there seem to be surprisingly few good introductions) but the one or two sites I cobbled something together that needed to change existing things instead of just adding more, I did something pretty fragile with string replacing. Should probably ask how to do it better, but that's for a different thread (and time when I actually care).

    I've done things like replace a "show adblock message" function triggered by a setTimeout with a no-op, but so far never had to inject my own version of string.length


  • BINNED

    @hungrier in that case usually blocking the no-adblock-script works. 🏆
    Although I have "Adblock Warning Removal List" and "I don't care about cookies" 1 installed.

    1 I do care about your cookie tracking, but since they are all routed to /dev/null I don't care about those fake opt-in dialogs.


Log in to reply