For anyone designing a programming language, enforce namespace to includes/imports! and if possible, don't allow top level side effects.
let foo = include "lib/foo.hurl"
foo.init()
it's much easier to reason about then, for example:
include "lib/foo.hurl" // side effects
baz(buz) // function and variable that I have no idea if they are in the standard library, or included *somewhere*
I do not disagree, but I use IntelliJ for work and it shows clearly where some reference is imported from and let you navigate to it with a shortcut. VSCode does similar things with plugins and LSP, just much worse. I cannot work in VSCode because navigating code is so slow. Is this suggestion only useful when you don’t have such tools? It seems impossible to me that people can live without them, at least in a professional setting.
I forked Ruby to have require that didn't clobber the symbol table but then lost interest in Ruby itself because the ecosystem seems unhinged on shared global mutable state.
This is precisely why I stopped using Nim. I was going crazy trying to remember what functions were called etc. I could do from x import nil but it felt like fighting the language.
I've always kinda hated exceptions as it makes the contract between a caller and a callee hard to determine, and makes your code highly coupled. I prefer the Go or Rust style of handling it through return values. Briefly skimming the language, I'm not sure if there is anything that fixes that?
I think this kind of model could be cool if your IDE could dynamically determine all uncaught exceptions for a function, and lets you jump to each possible place where the exception could be thrown. Not sure how you handle coupling though. This seems like it would result in an insanely volatile control flow graph.
This is what IntelliJ does for Java. A problem is reported whenever you have a function that throws exceptions and isn’t caught in a caller anywhere in the project, and you can jump to implementation or calls easily.
However, exceptions that a function can throw are part of the function signature in Java unless they extend RuntimeException (and in that case your program won’t compile if you throw an exception without adding it to the signature). While the circumstances in Java make it much easier for IDEs to report uncaught exceptions, it’s a solvable problem for non-runtime exceptions using static analysis.
On the other hand, returning standardised Ok/Err-wrapped values seems like a simpler approach, both in terms of tooling support and developer convenience.
> ...as it makes the contract between a caller and a callee hard to determine, and makes your code highly coupled. I prefer the Go or Rust style of handling it through return values.
There is literally (literally!) no difference at all between throwing and exception and returning it as a variable. Except for the fact that in the exception passing style you have to write the boilerplate by hand, instead of letting the compiler do it for you.
Why anybody with a sane and functioning brain would want to do that by hand in 2024 I will never understand.
If go didn't naturally eat error context, I'd like it more. But in the time I've used it, it makes errors much, much more painful to root cause without a debugger.
> Now let's see an example with toss. This is used mostly for passing multiple values out of the function. You don't really need it, but it's cute.
Not useful? You've implemented resumable generators! Of course, getting them to do anything except resume immediately might be... exciting. :P Just need to structure your entire codebase as an inside-out stack of `toss`es...
Not quite, since with resumable generators you can resume at any later point in the program, while here "return" must be lexically scoped to the handler (whereas in e.g. Python you can call next() wherever).
This is really more like passing a callback through a side channel. "toss" is invoking said callback, and "return" is, well, returning from it.
Yeah that made me chuckle. I wish the languages I use had resumable exception handling. This is a ridiculously good, and extremely useful feature. Great for API callbacks, among other things.
Not related to the project as such, but I am firmly of the opinion that the world would be a better place if more things used the .wtf extension for their domain :)
I never understood "algebraic effects". But I understand the Hurl docs. Are "algebraic effects" basically the "toss" keyword from Hurl? If so, how are "algebraic effects" stronger than the "toss" keyword?
Nice thought experiment.
I absolutely hate exceptions and I'd like a language without exception.
They're the goto of our time.
When we have Maybe/Option and Effect/Result, there is really no reason to throw exceptions and having to mentally track where that is being handled.
I'm a bit worried about algebraic effects becoming more popular (and influencing frontend JS - which is already way too complex) because it's promoting throwing "exceptions" to control the flow. All of this to avoid the coloring problem in async/sync? Absolutely not worth it imho.
Wow, I hate this. But it’s … oddly almost kinda elegant? In a very hard to mentally model way, but even so.
Speaking more seriously than is perhaps warranted, I’d slightly prefer it if there were syntactically different “catch” constructs for resumable and nonresumable exceptions, which would remove syntactic ambiguity around whether “return” was sending control flow back to the thrower of the nearest immediate exception or not.
Also, the stdlib shouldn’t have chickened out with regular value-returning functions. Just because the dogfood gives you heartburn doesn’t mean you shouldn’t eat it :)
> Also, the stdlib shouldn’t have chickened out with regular value-returning functions. Just because the dogfood gives you heartburn doesn’t mean you shouldn’t eat it :)
Yes, although an alternative would be to make the syntax if you call the function where a value is expected, then it will automatically catch.
'Toss' sounds like an interesting language construct: it walks the stack to find an exception handler and then walks back to where it was to resume execution as if nothing happened. It looks like you can inject additional behavior at runtime using this construct. Usually in object-oriented code you do dependency injection using services's constructors, but 'toss' allows to do it using "toss handlers"?
This is quite similar to the Common Lisp conditions system… which I actually don’t know much about, but I do know that it lets you inject behaviour at runtime like this does.
Multiple products sharing a name is unavoidable. Github had 90,000 unique repositories in its first year. If each had to have a unique name, it would almost have exhausted the English dictionary. In 2018, it reached 100 million repositories.
Also my thought. It's very interesting how the designers of this language, presumably unaware of algebraic effects, write about it as if it a terrible joke when this is actually one of the trendiest ideas in PL.
[+] [-] z3t4|1 year ago|reply
[+] [-] remram|1 year ago|reply
import "foo/bar" should make foo.* OR bar.* available, not bazz.*. I'm looking at you, Go.
[+] [-] Wonton56|1 year ago|reply
[+] [-] BoppreH|1 year ago|reply
[+] [-] moomin|1 year ago|reply
(Don’t confuse this with me thinking this project is worthless, I think it’s art.)
[+] [-] lhfasufdowedfs|1 year ago|reply
I forked Ruby to have require that didn't clobber the symbol table but then lost interest in Ruby itself because the ecosystem seems unhinged on shared global mutable state.
[+] [-] manusachi|1 year ago|reply
For that very reason in Elixir `import` is discouraged in favor of `alias`
[+] [-] sergiotapia|1 year ago|reply
[+] [-] packetlost|1 year ago|reply
[+] [-] djha-skin|1 year ago|reply
Critiquing a joke design is of dubious usefulness, at best :)
[+] [-] zeroCalories|1 year ago|reply
I think this kind of model could be cool if your IDE could dynamically determine all uncaught exceptions for a function, and lets you jump to each possible place where the exception could be thrown. Not sure how you handle coupling though. This seems like it would result in an insanely volatile control flow graph.
[+] [-] mbmjertan|1 year ago|reply
However, exceptions that a function can throw are part of the function signature in Java unless they extend RuntimeException (and in that case your program won’t compile if you throw an exception without adding it to the signature). While the circumstances in Java make it much easier for IDEs to report uncaught exceptions, it’s a solvable problem for non-runtime exceptions using static analysis.
On the other hand, returning standardised Ok/Err-wrapped values seems like a simpler approach, both in terms of tooling support and developer convenience.
[+] [-] otabdeveloper4|1 year ago|reply
There is literally (literally!) no difference at all between throwing and exception and returning it as a variable. Except for the fact that in the exception passing style you have to write the boilerplate by hand, instead of letting the compiler do it for you.
Why anybody with a sane and functioning brain would want to do that by hand in 2024 I will never understand.
[+] [-] NBJack|1 year ago|reply
[+] [-] kibwen|1 year ago|reply
Not useful? You've implemented resumable generators! Of course, getting them to do anything except resume immediately might be... exciting. :P Just need to structure your entire codebase as an inside-out stack of `toss`es...
[+] [-] int_19h|1 year ago|reply
This is really more like passing a callback through a side channel. "toss" is invoking said callback, and "return" is, well, returning from it.
[+] [-] 1propionyl|1 year ago|reply
Part of me wonders if it's a bit of a joke, panning a genuinely useful feature (in any other language) as disposable and silly (in this one).
[+] [-] boromisp|1 year ago|reply
[+] [-] DeathArrow|1 year ago|reply
Like yield in C#?
[+] [-] Vivtek|1 year ago|reply
[+] [-] kleiba|1 year ago|reply
[+] [-] adastra22|1 year ago|reply
[+] [-] masklinn|1 year ago|reply
[+] [-] Aeolun|1 year ago|reply
[+] [-] helix278|1 year ago|reply
[+] [-] levzettelin|1 year ago|reply
[+] [-] jokethrowaway|1 year ago|reply
They're the goto of our time.
When we have Maybe/Option and Effect/Result, there is really no reason to throw exceptions and having to mentally track where that is being handled.
I'm a bit worried about algebraic effects becoming more popular (and influencing frontend JS - which is already way too complex) because it's promoting throwing "exceptions" to control the flow. All of this to avoid the coloring problem in async/sync? Absolutely not worth it imho.
[+] [-] zbentley|1 year ago|reply
Speaking more seriously than is perhaps warranted, I’d slightly prefer it if there were syntactically different “catch” constructs for resumable and nonresumable exceptions, which would remove syntactic ambiguity around whether “return” was sending control flow back to the thrower of the nearest immediate exception or not.
Also, the stdlib shouldn’t have chickened out with regular value-returning functions. Just because the dogfood gives you heartburn doesn’t mean you shouldn’t eat it :)
[+] [-] zzo38computer|1 year ago|reply
Yes, although an alternative would be to make the syntax if you call the function where a value is expected, then it will automatically catch.
[+] [-] tempodox|1 year ago|reply
Also, I am concerned about how much Hurl I can write before people start calling me a tosser?
[+] [-] kgeist|1 year ago|reply
[+] [-] tylerhou|1 year ago|reply
https://koka-lang.github.io/koka/doc/book.html#why-handlers
[+] [-] bradrn|1 year ago|reply
[+] [-] mjbrusso|1 year ago|reply
[+] [-] DaveFlater|1 year ago|reply
[+] [-] ceving|1 year ago|reply
[+] [-] baq|1 year ago|reply
[+] [-] frithsun|1 year ago|reply
[+] [-] Alifatisk|1 year ago|reply
[+] [-] brundolf|1 year ago|reply
[+] [-] MidhaelBollox|1 year ago|reply
[+] [-] cushpush|1 year ago|reply
[+] [-] hgyjnbdet|1 year ago|reply
[0] https://hurl.dev/docs/manual.html
[+] [-] tgv|1 year ago|reply
[+] [-] samatman|1 year ago|reply
[+] [-] junon|1 year ago|reply
[+] [-] emersion|1 year ago|reply
[+] [-] tombert|1 year ago|reply
[+] [-] withoutboats3|1 year ago|reply
[+] [-] unknown|1 year ago|reply
[deleted]