First of, congrats on your efforts! Hope you guys continue working on great things with Gren. I've glanced over the book on your site but I've got some few questions: - Do we have type unions and intersections on the algebraic types? - Do we have support for recursive custom types? - Do we have any primitives for concurrent programming? - Do we have any primitives for input and streams? - Is equality and other binary relations part of the specification? Say, is equality between records deep or shallow? - What sort of control do we have over the underlying data structures? Say, contiguous vs linked memory, copy and move semantics, etc.
- Do we have type unions and intersections on the algebraic types? No. This might change in the future as we're thinking about revamping the algebraic datatypes feature. - Do we have support for recursive custom types? Yes. - Do we have any primitives for concurrent programming? Tasks are inherently concurrent, in the same way JS promises are concurrent. We currently don't have builtin support for parallelism, but we plan to investigate that prior to releasing 1.0. - Do we have any primitives for input and streams? We have very limited support for that right now, but a full Stream revamp is being worked on for the next release (December). I'm thinking on doing a preview of the new Stream stuff in November. - Is equality and other binary relations part of the specification? Say, is equality between records deep or shallow? Deep. Since everything is guaranteed to be immutable, `==` is implemented with shallow equality. - What sort of control do we have over the underlying data structures? Say, contiguous vs linked memory, copy and move semantics, etc. Limited control. Arrays are contiguous, and you can use recursive custom types for linked memory. No control over copy vs move. This is meant to be a higher-level language than Rust.
Roc has swappable platforms for runtime handling where Gren has stuck with the elm architecture. PureScript doesn't have a concept of a runtime as part of the architecture as far as I know. Roc has also been adding many features, while Gren has tried to stay small, even removing some features that Elm had. Roc has also been leaning into syntax sugar that lets you write code in an imperative style while Gren still feels like you're using a declarative, pure, functional language with explicit effect handling. A big difference from PureScript is that Gren has no direct FFI to javascript. This is a trade-off that makes it harder to use all the tools from the js ecosystem, but in exchange for absolute guarantees on how your code will behave at runtime.
@@daiske2867 To me: F# isn't pure, Scala isn't pure (also complicated/big and slow to compile), erlang/elixir are dynamicly typed (also not pure), gleam isn't pure, ocaml isn't pure, haskell has unchecked exceptions, is big/complicated and slow to compile.
Genuine ques Why the modern langs try to use type syntax in untraditional way variable : type = 100 why not do type variable = 100 In python, typescript, rust, swift, dart and here as well the syntax is to put type after, but it should be before like the old langs, because it sometime is more confusing when reading the code what is the var type and what is the return type of a function.
because typing is weaker in a lot of those languages so the name is more important than the type, python just has hinting, typescript types usually get complied away into js. So by having types after the name it makes it easier to integrate with untyped variables for example "x: int = 69;" next to "y = 420;" has the same placement of identifier and value
In some cases it's because the type annotation is optional (like in Gren), and I believe I've also read that having the type after simplifies the parsing (though I'm not sure why). > what is the var type and what is the return type of a function In Gren I believe this is very clear, as the last type is always the return value.
I think there are a lot of reasons, one being that it's easier to parse, the second being that it's easier to read once you are used to it, and it's also more coherent with the overall language if the type if always on the right. For example the C style const int *foo = NULL; reads like A const integer pointer called foo which is equal to NULL. vs a more modern Zig syntax, const foo : ?*i32 = null; Which reads. A constant foo of type Optionnal pointer to an integer of 32 bits initialized to null; At the end of the day it's not that big of a deal I come from a C background and now I'm toying a lot with Zig and Rust, and it's just a matter of getting used to this form of syntax, and after quite a bit I feel like it's a lot cleaner. It also disambiguate the storage specifier. So in C you can have : int *foo; // foo is a variable pointer to an variable integer const int *bar; // bar is a var pointer to a const integer int const *baz; // same for baz int *const bag; // bag is a const pointer to a var integer const int *const bad // const pointer to a const integer; int const *const bah // same for bah; Whereas in Zig you can have: var foo: ?*i32 = null; // her it's clearer, foo is var, and what it's pointing to is var too. const bar: ?*i32 = null // bar is const and what it's pointing to is var; var baz: ?*const i32 = null // baz is var and what it's pointing to is const ; const bag: ?*const i32 = null // bag is const and what it's pointing to is const; So in C this is really ambiguous, and it takes some knowing to disambiguate the meaning, but having the type on the right, and allowing storage specifier on the left and right allows to cleanly separate, what in the declaration is const ? is it our variable ? is it the things we are pointing to ? or is it both ?
recently i'm very interesed in the topic of compilers, do u have any recomendation of books or courses that helped you with the development of Gren ?, ps: very good vídeo
I'd recommend Crafting Interpreters heavily. Its an incredibily accesible learning-by-project-example introduction to compiler design and development. It got illustrations, code, everything, and its web version is free!
Additionally, the goold old Dragon Book is often recommended as an college-level textbook for compiler courses. It explores the fundamentals, including theory and design, while mantaining some rigor often put aside for pragmatic approaches
I believe deno is trying to be node compatible? Gren only uses built-in nodejs api's, as long as those are available then any Gren program should just work.
I don't like Haskell. I think it's overly complicated, slow to compile and not pure enough (unchecked exceptions). Purescript share many of the same flaws. It's also hard to convince people new to pure functional programming to learn Haskell/Purescript, whereas Elm seems to go ok.
@ it has full node api compatibility but supports web standards out of the box so isomorphic code is built in, ts support is built in so if we need to “break out” of gren we’re still able to use types, you’d get the ability to “Deno compile” gren apps into a single executable binary, you’d get compatibility with Tauri (the modern electron) which just add iOS capabilities so gren on iOS!, deno has a jupyter notebook kernel baked into the runtime so you could expose gren to a whole slew of data science users, deno had deno KV built in so in the runtime you have data persistence solution built in….a repl, CJS imports supported for libs ie “require” is supported in dependencies but ES6 imports enforced at the top level- these are all good things that are in line with your philosophy of standards and stability… just seems like a waste of a wonderful effort to latch onto the dinosaur 🦕 that is node-when deno gives you compat + a freaky amount of benefits. I was literally able to run deno 2.0 inside old repos that were “broken” because of the CJS / ES6+ incompatibility and it just solved it during the deno install-there’s big money and brains behind that project. Honorable mention: JSR (their legitimate npm replacement). Have you been living under a rock? Lol
@@efkastner I haven’t used Roc, but I believe Roc is first and foremost a backend language while Gren is full stack. Gren is also a smaller language than Roc.
12:18 choice being one of the worst productivity killers is a wildly hot take. I would maybe refine that statement a tad by saying "debating choice where it really doesn't matter" is a productivity killer. I recently got a new boss. We used to have a lot of free reign and ability to make what we believed was the correct choice to solve problems. My team was fast and efficient. My new boss is interested in discussing and debating and analyzing every little choice and we honest to God, have not actually written new code in 10 months. It's insane. The choices didn't change, they were always there. That said if you never take the training wheels off your bike, do you really know how to ride it? If you can't write function without a specifically functional language or write OO without a specifically OO oriented language... then do you really know it?
> I would maybe refine that statement a tad by saying "debating choice where it really doesn't matter" is a productivity killer. That's what I meant, but I agree that I could've been more clear on that. > That said if you never take the training wheels off your bike, do you really know how to ride it? I mean, you could make the same argument about gotos, garbage collection or Erlang's actor model. Relying on garbage collection arguably makes you worse at managing memory, but if managing memory isn't relevant to the product you're building then you can save a lot of time and effort by not having to worry about it. You still need skill to build an application. I just think it's better to use that skill on the choices that matter for the application that you're building.
Decision fatigue is a killer. @HalfMonty11 I empathize with you so much. I’ve been on a project for 3 years that has been plagued with questioning too many choices and the drag it has incurred!
If this video is intended for developers/programmers(most of which use dark mode for everything), then please consider a dark background for your videos, a full bright background would literally hurt a dark mode Dev eyes while a dark background hurts no one. I for one, was interested in your video but couldn't watch it because of that.
elm and js have a baby? oh no, no thank you. What is the advantage of companies and academia to adopt this language? You still need to know JS for debugging since the output is JS and I assume HTML?
> What is the advantage of companies and academia to adopt this language? That's what the first 30 minutes or so of the video is about. > You still need to know JS for debugging since the output is JS and I assume HTML? The output is JS. HTML is possible if you target the browser, but you can have backends in this as well. Gren has sourcemap support, so you can debug the actual Gren code. We also might compile to Wasm in the future.
Do you need to know assembly to debug C? It seems to compile to JS. You probably won’t have to interact with JS directly at all if you’re writing Gren. No different from CoffeeScript or Elm or any other front end language. That being said, you probably have to at least know JS to work on the web front end at all, no matter what tools you’re using.
@@wilkesreid If you want to write highly specialized and performant code you do... As a cpp dev I've read asm many times. If you work on a js based vm you do need to know js like a c dev needs to know their os and asm.
A stray function named 'doubleAge' that takes in a Person object and returns a Person object, should by all means not mutate the original object... If it was a method of Person, it would make sense for it to both mutate and return a reference to the same Person, so that it can be chained But a stray function that cannot be chained should not mutate if it returns a Person. I am afraid that this ain't a language problem, but a skill issue.
As I mentioned in the video, coming up great examples is hard so don't focus on the literal code. Rather, focus on the fact that the code can do pretty much anything no matter what the names, types or best practice indicate, because the language doesn't limit it in any way. The point isn't what the code should or should not do, it's that you cannot know what it does without checking. Will you or your team write code that makes use of all the potential pitfalls I mention in the video? Maybe not. Could the things I point out make it hard to spot security issues or otherwise bad behaviour in code you rely on but haven't written yourselves? Quite likely. Further, would it be better to focus your skill away from such issues entirely? In my case, yes. Knowing for a fact what a function can and cannot do without needing to read the implementation makes it easier and faster to find the pieces of code that are problematic.
You're right. What I like about Gren, and what Robin is pointing out with that example, is that it's not even possible to mutate. So instead of relying on someone's skill, you can just depend on the compiler.
@@robinheggelundhansen sadly we don't live in a world where such languages will be the go-to for any project look at Rust, with it's ownership pattern your example would not be a skill issue as well, sadly most programmers fear the unknown, they find comfort in what they learnt at uni, be C++, Java or C
Maybe it shouldn’t, but it still could. You don’t always have the privilege of working on a team where all the other devs will behave themselves or use good practice. And when you’re debugging, it’s good to know what can and can’t be going on.
33:34 time to actually get to talking about the language.
Well he wasn't babbling, there was a well deserved introduction.
Also he provided timestamps.
😂
First of, congrats on your efforts! Hope you guys continue working on great things with Gren.
I've glanced over the book on your site but I've got some few questions:
- Do we have type unions and intersections on the algebraic types?
- Do we have support for recursive custom types?
- Do we have any primitives for concurrent programming?
- Do we have any primitives for input and streams?
- Is equality and other binary relations part of the specification? Say, is equality between records deep or shallow?
- What sort of control do we have over the underlying data structures? Say, contiguous vs linked memory, copy and move semantics, etc.
- Do we have type unions and intersections on the algebraic types?
No. This might change in the future as we're thinking about revamping the algebraic datatypes feature.
- Do we have support for recursive custom types?
Yes.
- Do we have any primitives for concurrent programming?
Tasks are inherently concurrent, in the same way JS promises are concurrent. We currently don't have builtin support for parallelism, but we plan to investigate that prior to releasing 1.0.
- Do we have any primitives for input and streams?
We have very limited support for that right now, but a full Stream revamp is being worked on for the next release (December). I'm thinking on doing a preview of the new Stream stuff in November.
- Is equality and other binary relations part of the specification? Say, is equality between records deep or shallow?
Deep. Since everything is guaranteed to be immutable, `==` is implemented with shallow equality.
- What sort of control do we have over the underlying data structures? Say, contiguous vs linked memory, copy and move semantics, etc.
Limited control. Arrays are contiguous, and you can use recursive custom types for linked memory. No control over copy vs move. This is meant to be a higher-level language than Rust.
@@robinheggelundhansen Thank you for the reply! Best of luck in your efforts.
What do you think about Roc lang which attempts to be Elm for backend?
Roc has swappable platforms for runtime handling where Gren has stuck with the elm architecture. PureScript doesn't have a concept of a runtime as part of the architecture as far as I know. Roc has also been adding many features, while Gren has tried to stay small, even removing some features that Elm had. Roc has also been leaning into syntax sugar that lets you write code in an imperative style while Gren still feels like you're using a declarative, pure, functional language with explicit effect handling. A big difference from PureScript is that Gren has no direct FFI to javascript. This is a trade-off that makes it harder to use all the tools from the js ecosystem, but in exchange for absolute guarantees on how your code will behave at runtime.
@@jblaix thanks!
Hello from Stavanger, Good to see another Devbox user. Nice presentation of your language
Amazing work! I've been waiting for the Elm implementation for the backend.
what are the problems with using: f#(for .NET fun), Scala(for Java fun), erlang/elixir/gleam, ocaml, haskell?
@@daiske2867 To me: F# isn't pure, Scala isn't pure (also complicated/big and slow to compile), erlang/elixir are dynamicly typed (also not pure), gleam isn't pure, ocaml isn't pure, haskell has unchecked exceptions, is big/complicated and slow to compile.
Modern Softwere Development is like modern audience in entertainment industry?
Touch grass
Genuine ques
Why the modern langs try to use type syntax in untraditional way
variable : type = 100
why not do
type variable = 100
In python, typescript, rust, swift, dart and here as well the syntax is to put type after, but it should be before like the old langs, because it sometime is more confusing when reading the code what is the var type and what is the return type of a function.
because typing is weaker in a lot of those languages so the name is more important than the type, python just has hinting, typescript types usually get complied away into js. So by having types after the name it makes it easier to integrate with untyped variables for example "x: int = 69;" next to "y = 420;" has the same placement of identifier and value
In some cases it's because the type annotation is optional (like in Gren), and I believe I've also read that having the type after simplifies the parsing (though I'm not sure why).
> what is the var type and what is the return type of a function
In Gren I believe this is very clear, as the last type is always the return value.
I think there are a lot of reasons, one being that it's easier to parse, the second being that it's easier to read once you are used to it, and it's also more coherent with the overall language if the type if always on the right.
For example the C style const int *foo = NULL; reads like A const integer pointer called foo which is equal to NULL. vs a more modern Zig syntax, const foo : ?*i32 = null; Which reads. A constant foo of type Optionnal pointer to an integer of 32 bits initialized to null;
At the end of the day it's not that big of a deal I come from a C background and now I'm toying a lot with Zig and Rust, and it's just a matter of getting used to this form of syntax, and after quite a bit I feel like it's a lot cleaner. It also disambiguate the storage specifier.
So in C you can have :
int *foo; // foo is a variable pointer to an variable integer
const int *bar; // bar is a var pointer to a const integer
int const *baz; // same for baz
int *const bag; // bag is a const pointer to a var integer
const int *const bad // const pointer to a const integer;
int const *const bah // same for bah;
Whereas in Zig you can have:
var foo: ?*i32 = null; // her it's clearer, foo is var, and what it's pointing to is var too.
const bar: ?*i32 = null // bar is const and what it's pointing to is var;
var baz: ?*const i32 = null // baz is var and what it's pointing to is const ;
const bag: ?*const i32 = null // bag is const and what it's pointing to is const;
So in C this is really ambiguous, and it takes some knowing to disambiguate the meaning, but having the type on the right, and allowing storage specifier on the left and right allows to cleanly separate, what in the declaration is const ? is it our variable ? is it the things we are pointing to ? or is it both ?
Type inference and LSP's are frendlier with postfix types than prefix types.
@@robinheggelundhansen
Yes then it make sense now.
On the parser and the optional typing point.
recently i'm very interesed in the topic of compilers, do u have any recomendation of books or courses that helped you with the development of Gren ?, ps: very good vídeo
Don't really have good recomendations for books or courses. I've mostly learned by reading source code.
I'd recommend Crafting Interpreters heavily. Its an incredibily accesible learning-by-project-example introduction to compiler design and development. It got illustrations, code, everything, and its web version is free!
Additionally, the goold old Dragon Book is often recommended as an college-level textbook for compiler courses. It explores the fundamentals, including theory and design, while mantaining some rigor often put aside for pragmatic approaches
@@luigikart222 thanks for the recomendation, i'll take a look
@@lucasmartins-mk2jp Np! Hope it helps a ton
if gren also runs on deno (they just had a huge upgrade), then i might start my next small project in gren
I’m sure they’ll eventually introduce deno, bun, etc as compilation targets
I believe deno is trying to be node compatible? Gren only uses built-in nodejs api's, as long as those are available then any Gren program should just work.
🎉THANK YOU SO MUCH! 🎉🎉🎉🎉
JavaScript is like C and COBOL. Buried in the software body like a tick
Great work Robin!
I get ELM for frontend
But if you are exclusively targeting backend why wouldn't I just use haskell
Or if you really love js purescript at that point
I don't like Haskell. I think it's overly complicated, slow to compile and not pure enough (unchecked exceptions). Purescript share many of the same flaws.
It's also hard to convince people new to pure functional programming to learn Haskell/Purescript, whereas Elm seems to go ok.
This reminds me a lot like Erlang
Nice logo 👍🏻
I like your ideas but I am not sure if I like gren
is this a play on wren lang?
gren-lang.org/book/appendix/faq/
Great video!
why not deno?
What would be the benefit of Deno?
@ it has full node api compatibility but supports web standards out of the box so isomorphic code is built in, ts support is built in so if we need to “break out” of gren we’re still able to use types, you’d get the ability to “Deno compile” gren apps into a single executable binary, you’d get compatibility with Tauri (the modern electron) which just add iOS capabilities so gren on iOS!, deno has a jupyter notebook kernel baked into the runtime so you could expose gren to a whole slew of data science users, deno had deno KV built in so in the runtime you have data persistence solution built in….a repl, CJS imports supported for libs ie “require” is supported in dependencies but ES6 imports enforced at the top level- these are all good things that are in line with your philosophy of standards and stability… just seems like a waste of a wonderful effort to latch onto the dinosaur 🦕 that is node-when deno gives you compat + a freaky amount of benefits.
I was literally able to run deno 2.0 inside old repos that were “broken” because of the CJS / ES6+ incompatibility and it just solved it during the deno install-there’s big money and brains behind that project.
Honorable mention: JSR (their legitimate npm replacement).
Have you been living under a rock? Lol
yeah but can it serialize and deserialize json?
Yeah. Json.Encode and Json.Decode modules in the gren-lang/core package.
Any programming language can.
Just make one if it can't
Ever heard of Rock - Richard Feldman?
@@megetmorsomt Roc. Richard and I were both part of the Elm core team, and know of each other’s efforts.
I’ve been following his stuff on and off for a few years but haven’t actually tried Roc. Can you compare Gren to Roc a bit?
@@efkastner I haven’t used Roc, but I believe Roc is first and foremost a backend language while Gren is full stack. Gren is also a smaller language than Roc.
I am not a fan of json for the configuration
2 years brother? McTease with Cheese
I'd love Gren to be the goto language for smart contracts
Wtf happened to Wren?
Interesting ideas.
12:18 choice being one of the worst productivity killers is a wildly hot take.
I would maybe refine that statement a tad by saying "debating choice where it really doesn't matter" is a productivity killer. I recently got a new boss. We used to have a lot of free reign and ability to make what we believed was the correct choice to solve problems. My team was fast and efficient. My new boss is interested in discussing and debating and analyzing every little choice and we honest to God, have not actually written new code in 10 months. It's insane. The choices didn't change, they were always there.
That said if you never take the training wheels off your bike, do you really know how to ride it? If you can't write function without a specifically functional language or write OO without a specifically OO oriented language... then do you really know it?
> I would maybe refine that statement a tad by saying "debating choice where it really doesn't matter" is a productivity killer.
That's what I meant, but I agree that I could've been more clear on that.
> That said if you never take the training wheels off your bike, do you really know how to ride it?
I mean, you could make the same argument about gotos, garbage collection or Erlang's actor model. Relying on garbage collection arguably makes you worse at managing memory, but if managing memory isn't relevant to the product you're building then you can save a lot of time and effort by not having to worry about it.
You still need skill to build an application. I just think it's better to use that skill on the choices that matter for the application that you're building.
Decision fatigue is a killer. @HalfMonty11 I empathize with you so much. I’ve been on a project for 3 years that has been plagued with questioning too many choices and the drag it has incurred!
Nice project
are you wren's author?
that also had a bird too i think for logo 🤔
No.
If this video is intended for developers/programmers(most of which use dark mode for everything), then please consider a dark background for your videos, a full bright background would literally hurt a dark mode Dev eyes while a dark background hurts no one. I for one, was interested in your video but couldn't watch it because of that.
Leave him alone-it’s not easy creating rich content and let alone satisfying a fast number preferences
I watched it on the phone, completely fine, I get how you would feel bombarded on a monitor
Maybe you should see a doctor or learn to adjust screen brightness
youre soft
@@KatarDanwhat if my doctor told me to use dark mode
elm and js have a baby? oh no, no thank you.
What is the advantage of companies and academia to adopt this language?
You still need to know JS for debugging since the output is JS and I assume HTML?
> What is the advantage of companies and academia to adopt this language?
That's what the first 30 minutes or so of the video is about.
> You still need to know JS for debugging since the output is JS and I assume HTML?
The output is JS. HTML is possible if you target the browser, but you can have backends in this as well.
Gren has sourcemap support, so you can debug the actual Gren code.
We also might compile to Wasm in the future.
Do you need to know assembly to debug C? It seems to compile to JS. You probably won’t have to interact with JS directly at all if you’re writing Gren. No different from CoffeeScript or Elm or any other front end language. That being said, you probably have to at least know JS to work on the web front end at all, no matter what tools you’re using.
@@wilkesreid If you want to write highly specialized and performant code you do...
As a cpp dev I've read asm many times.
If you work on a js based vm you do need to know js like a c dev needs to know their os and asm.
@@robinheggelundhansen The only thing i can think of is a compamy using elm and wants to shift...
That's really the only reason.
A stray function named 'doubleAge' that takes in a Person object and returns a Person object, should by all means not mutate the original object...
If it was a method of Person, it would make sense for it to both mutate and return a reference to the same Person, so that it can be chained
But a stray function that cannot be chained should not mutate if it returns a Person.
I am afraid that this ain't a language problem, but a skill issue.
As I mentioned in the video, coming up great examples is hard so don't focus on the literal code. Rather, focus on the fact that the code can do pretty much anything no matter what the names, types or best practice indicate, because the language doesn't limit it in any way. The point isn't what the code should or should not do, it's that you cannot know what it does without checking.
Will you or your team write code that makes use of all the potential pitfalls I mention in the video? Maybe not. Could the things I point out make it hard to spot security issues or otherwise bad behaviour in code you rely on but haven't written yourselves? Quite likely.
Further, would it be better to focus your skill away from such issues entirely? In my case, yes. Knowing for a fact what a function can and cannot do without needing to read the implementation makes it easier and faster to find the pieces of code that are problematic.
You're right. What I like about Gren, and what Robin is pointing out with that example, is that it's not even possible to mutate. So instead of relying on someone's skill, you can just depend on the compiler.
@@robinheggelundhansen sadly we don't live in a world where such languages will be the go-to for any project
look at Rust, with it's ownership pattern your example would not be a skill issue as well, sadly most programmers fear the unknown, they find comfort in what they learnt at uni, be C++, Java or C
Maybe it shouldn’t, but it still could. You don’t always have the privilege of working on a team where all the other devs will behave themselves or use good practice. And when you’re debugging, it’s good to know what can and can’t be going on.
@@wilkesreid on those same conditions, you wouldn't use a language like this, because you wouldn't be the one making the decision
But still is JavaScript. Cool project though