The Dream Programming Language? Lobster
Вставка
- Опубліковано 1 кві 2023
- A concise walkthrough of Lobster, a programming language that has a Python-like syntax but is statically typed with next-level inference and does not rely on a garbage collector.
-
Camera: Canon EOS R5 amzn.to/3CCrxzl
Monitor: Dell U4914DW 49in amzn.to/3MJV1jx
SSD for Video Editing: VectoTech Rapid 8TB amzn.to/3hXz9TM
Microphone 1: Rode NT1-A amzn.to/3vWM4gL
Microphone 2: Seinheiser 416 amzn.to/3Fkti60
Microphone Interface: Focusrite Clarett+ 2Pre amzn.to/3J5dy7S
Tripod: JOBY GorillaPod 5K amzn.to/3JaPxMA
Mouse: Razer DeathAdder amzn.to/3J9fYCf
Keyboard (sometimes): Keychron Q1 amzn.to/3YkJNrB
Computer: 2021 Macbook Pro amzn.to/3J7FXtW
Lens: Canon RF24mm F1.8 Macro is STM Lens amzn.to/3UUs1bB
Caffeine: High Brew Cold Brew Coffee amzn.to/3hXyx0q
More Caffeine: Monster Energy Juice, Pipeline Punch amzn.to/3Czmfox
Building A Second Brain book: amzn.to/3cIShWf - Наука та технологія
"Languages faster than python are more common like hydrogen atoms" 😆 🤣
People are always just referring to runtime speed, not development speed or the learning curve.
@@NoidoDev But that is what speed *should* refer to. How your app performs in production is more important than the development, but that's my opinion
@@NoidoDev ok, you lanched your app in three days. now add a new feature without breaking everything. try to factor out a type. even in this parameters python is slow
I love everything about this. That's why I use Nim. It has almost all of these features, except for the hardcore inference, but is much more mature. Yes, including the memory system.
A LOT of these newer languages seems to be re-implementing features that are already extremely mature in Nim. I'm still shocked it has so little reach given that people keep making languages that do what it does incredibly well, and has done for a decade. But PLs are a hype-driven domain. New and weird always seem to beat older and stable.
Nim compiler errors really suck, and the syntax is too loose (some_func and someFunc are the same thing).
@@JustSomeAussie1 that is a turnoff
@@JustSomeAussie1 Yeah that's the reason I dropped nim. Too many ways to the same thing = confusion when reading someone else's code.
tbh the hardcore inference is the only thing that really caught my eye. The other features seem nice but kinda like double-edged swords (and not in a "this might lead to bad practices because it makes you lazy" way. Rather in a "the language has structural limitations on what it can do now because it bent over backwards to support this neat syntactic sugar" way).
I wish TypeScript's inference got this good
A lot of stuff in Lobster reminds me of Koka, especially all the syntax sugar. It also has indentation based scopes but those are defined as implicit brackets (and code is desugared to those brackets).
Parameter type inference is standard in the ml family(eg:F#). The dev ex is a little better as the ide will show the inferred types so you get all the benefits of specifying the type without having to write it out.
@8:56, it kinda looks a little more concise than Python 2/3 because there is no constructor in the class definition or dataclass decorator (pls ignore the `let` keyword)
Indentation for scopes sucks so bad
Wish you covered memory management more in depth.
Thanks for the great video! I found a little audio issues like some "pops" in between and maybe this info would help you sort that issue out (I initially thought that it had something to do with my headphone but then I confirmed it by listening from the laptop speaker)! (keep the good work going btw!)
I also get these pops. They are also in the Leaps for neovim video
Something that I have grown to accept about coding as I've gone further along, is that, in the words of Tim Peters: "Explicit is better than implicit"
I actually mostly agree with the spirit of that statement, but I also think that, as with many of these types of blanket statements - there are always exceptions
The problem I can see here is variable mutation. Albeit you have let/var, if the let contains class you are able to modify the class instance itself assigned to that name.
The type inference looks very powerful. I tried F#, but this thing is on another level. Curious how it works under the hood, but it seems like Go duck typing or C++ templates, but you don't need to declare interface or specify parameter type. Never seen something like that in a statically typed language.
that was my impression as well! Seems like it gives us pretty much all the advantages of dynamic typing, but with none of the downsides
what font are you using. Reminds me a lot of Code New Roman...
Not for me. For one, most of this video was focused on syntax, which is the _one_ thing I would change about Rust (I'd rather it looked more like Haskell, but oh well), but mainly I like Rust because it gives explicit control and tight restrictions that let me use that control without worrying. The language will automatically allocates if it can't solve the ownership? That's a deal breaker for me. What if I don't _have_ an allocator to begin with?
Concise, fun vid.
Good stuff.
This is exactly the mix of simlicity and terseness that I would expect from a good game dev, it kinda looks like a python+lua with types :D
+ Compiled and with Memory management
+ Compiled and with Memory management
most languages that I've seen with hindley-milner type inference make it necessary to declare types for function signatures (although fundamentally it isn't necessary). Cool vid!
my initial thought is that I think that its possible to be so concise so as to be harder to reason about and in my opinion this, at least, treads that line. Its like, you COULD make a Venn Diagram without the circles but does it actually make it better?
Yeah I know what you mean. I think about golang along these lines.
It is so concise because Lobster thinks these things (like trailing lambdas) are more fundamental than other languages do, and wants to make them as easy to use as built-in control structures for example. There are ways to make lambdas / types more verbose if you want, but yes, if you dislike looking at concise code in general then Lobster is not for you :)
@@WoutervanOortmerssen I do like concise code, up to but not including figuring out what I meant. Concise but formal and well-defined syntax is a must for me.
I just wrote my first program in lobster and love the syntax. Only issue I have is that there's no method chaning ie: filter().map()
What is the point of the parameter type determining whether it is passed by value or reference, rather than the caller making that choice?
How does it deal with reference cycles
for the next one I'd like to hear your summary/thoughts on lean4 prover functional programming language
And Glamorous Toolkit in Pharo for interactive (live objects) development style will also be cool.
Please make a video on Cone lang, I found it through C3 lang. Love your thoroughness 😍
The type inference for functions seems to work like Julia, which is even more powerful because of its multiple dispatch.
Except Julia will default to dynamic typing if it can't infer types, and Lobster will error :)
Does it have a binding library for Python, such as PyO3 of Rust? It would be great to write Python libraries in Lobster.
Have you tried Nim? It's fairly similar to Lobster, but more mature and does have Python bindings
@@matrix07012 I listened to you and checked Nim. I always knew that Nim users love it, but until your comment I have never checked it. I have to say WOW. This is amazing. Thanks for your proposal!
This looks like my dream programming language
Flying cars in 1985? 😂 Great video!
Strange... It looks like Rust, Nim, Crystal and Python had a baby... ;P
How do I run the code? for lobster
nice memory management features but type inference and no pattern matching :(. thank you so much for the tour, well done!
thanks for watching!
hi, what editor do you use ?
12:27 maybe a better way to execute the *_x* notation, where x is a-z, would be to type *$n* , where n is 0-infinity, a bit more flexible
everything else seems awesome
I guess if you need more than 26 parameters for a function you definitely have bigger problems 😅
@@IMJamby Yeah, I guess you're right. I still think my solution is bit more intuitive, and of course since I'm biased, but you're totally right
@@soyitiel $1 looks confusing and noisy. it's fine in bash but I much prefer _a * _b than $1 * $2. the former feels better to type as well as being easy on the eyes.
Which colorscheme is this in vim?
I believe it was "Sonokai"
8:19 this wild Type Inference wouldn't really fit in rust because (talking for myself) there's no clear way on how to solve conflicting names (yeah, I guess just import as a different name), I feel like might incur heavier compile times.
Weird or hard ABI(?) interface support
Rust Compiler was designed to only see your function signature at callsite. It then checks if the defined Function Signature matches with the body. It is a bit easier to make sense imo because you would only be worried that you work with whatever was defined in the function signature, however I agree this gives an advantage towards fast prototyping
Great video. The author has listed 'consider using something else instead of _ for namespaces' in his todo list. I guess it's possibly a concern if you use _ in your variables.
thank you! yeah I heard this issue was going to be addressed which seems like a great thing
Hi, how can I run a Lobster file?
I don't understand how that is memory management if it isn't garbage collected? Do you have to manually call something that's like "clear any memory with no ownership"?
nope - it uses automatic reference counting under the hood. So you get the same benefits as a garbage collected language in terms of not having to manually manage memory, but the runtime overhead is more predictable (and in some cases, non-existent). My understanding is that it doesn't handle cycles though.
Hmmm, not really a fan of having so many syntactical subtleties. I am a fan of having one way to do things
Reminds me of scala, both with syntax and static type inference. Will be cool to see if the memory management works as intended.
Agree on both points!
Doesn't seem to have algebraic datatypes and pattern matching?
I think that's correct
For implicit ownership memory management it comes down to how often can the compiler remove reference counting. If it can not do it's job well you end up with one of the worst kind of GC.
why is RC the worst kind of GC?
What's the font?
The duck typing and anonymous function as last argument syntax is very Ruby-esque.
Definitely - the really cool thing though is that you get static type checking at compile time, despite the syntax being concise like Ruby!
I thought this programming languages main method of memory management is compile time "static reference counting" & not some automatic form ownership & borrowing?
I have a beginner question: when you talk about faster than python, does it mean faster to write, faster to compile, or faster to run? Or all of them?
Faster to compile and faster to run.
The more low level you'll go the faster the language in those manners.
Python < Java/pHp < C/C++/Rust < Assembly languages
Assembly is the fastest (hardest also) among of all.
@@smallSphere69 I see, thank you for replying!
Hmm, "yet another language". :P
indeed!
Took what makes C and rust so great and threw it out the window...
(talking about curly brackets)
And decided to base itself on Python 😢
At the beginning of the video:
Lobster what?
At the end of the video:
It looks really interesting👍
This language is like my high school essays. I had zero unique ideas to say so I copied sentences from articles on the web and called it a new article
I think of programming languages like recipes - cheese, tomato sauce and bread all existed before pizza. But despite that, pizza is still novel (and amazing) isn't it?
@@codetothemoon Yeah, if you are treating languages like pizza, then you will find even programming the temperature controller of a pizza oven hard. ;-)
The inference of duck-typing is pretty cool.
I agree!
Can you give us their official website ?
Does it have multi-inheritance or traits or interfaces or something?
Nope, currently just single inheritance.. that has so far worked well for gamedev and its "functional" orientation. Its easy to do the equivalent of interfaces informally with static duck typing, i.e. "this will work on any type with a foo method" but there is no way to specify that formally currently.
Multi-inheritance really means you are not classifying anymore, single inheritance gives way to a tree structure of mutually-excluding classes whereas multi-inheritance's structure is latticial and results in not necessarily mutually excluding kinds while still ontologically permitting generalization and particularization. The hype for exclusive classes has always been a hindrance to me. I prefer kinds to classes. However, not much programming will be affected by lacking multi-inheritance, whose implementation I suspect may complicate matters a lot (compiler, memory management, optimization...).
3:00 these are not "structs as in C#" - there one can mutate fields
What I never get: If you already lean on the snytax of another language: Why these arbitrary divergence, e.g. the curly brackets for instantiation? It doesn't need to be a perfect clone of python, but differing arbitrarily just makes it harder to switch.
Wow, this is close to perfect.
wow, looks really interesting!
i agree!
It kinda put itself in the toy language category the moment it stated in "What lobster is not" that it is not suitable for big projects.
I agree it's a bit ominous of a statement to see when you're deciding whether to invest time in learning a new language
The author claims Lobster is not for AAA games because it lacks features that smaller creators probably don't want and what big studios do want. It's like the difference between coding proprietary software for game development and using a game engine. Many AAA game companies don't use Unity or Unreal because they need something specific to their complex needs and these game engines get in the way of that.
So Lobster is like Unity in that large studios might not want to use it for their projects.
Calling such languages "toy languages" is the problem. Some people need something powerful to work on their own projects, without a team.
Haha, Another crustacean library ( i see what they did there ). Lets call it the Seafood stack😂
LoL sounds good to me 🦀🦞🦐
interesting language to toy around with
8:15 That's just what the Scopes language does.
8:55 Oh, I never thought, this is one of the coolest features of Scopes. Even if I like that feature, it didn't seem that special to me.
The coolest feature of Scopes, despite having a bunch of fancy features, is the handling of references:
- if a is a reference, a.b is a reference, even if you assign them to a temporary name
- if a is a value, a.b is a value
- you can only assign to references, values are immutable
- most of the time you don't create variables, when you create variables explicitly, they normally don't point to an existing value
April 1st right
I am making my own language. It aims to merge Zig and Rust together, and aims to solve flaws like relying on an Internet connection just to compile.
i've been trying this language for about 3 weeks but havent found any way to operate with bigInts or insanely big numbers, the closest to that is using floats but still overflows eventually, if anyone had found a way to use bigInts with the integrated libs or functions that this language has, please let me know :D
maybe check with the folks on the Lobster discord server, I think Wouter is pretty active there!
@@codetothemoonwow, i didnt knew there was a discord server, please, may you tell me where to find the link? hope i dont bother you, and thanks!!
discord.gg/szJPYdX@@mistical1409
@@codetothemoonThank you very much!! you earned a new sub! :D
So the signature for instantiating an object depends on whether a default value was specified within the class? That is just all kinds of horrible.
Aren’t structs also passed by reference but act as if it was by value because they are immutable?
they are actually passed as a copy at an implementation level, which is actually faster for the common use case of 2d/3d vector types.. they could be made mutable, just haven't gotten to that
Good to know thank you!
Whenever I see the **def** keyword in a language, I already know it favors brevity over clarity.
why is that?
@@codetothemoon Def is meaningless. Def what? Leopard? Oh, it's short for define? So functions are defined but not the rest of the program? Function is more descriptive. Why is it so hard to spell out keywords, especially when there's no screen real estate penalty, powerful text editors, and Language Servers. In my experience, brevity also carries with it laziness and sloppiness in the language designers as well as the person programming in it. Don't believe me? C/C++ code is ugly and sloppy when compared to Pascal or Ada.
the cars location is actually a location on a space filling curve
whoa... this is the game developer who made the cube and sauerbraten fps games that have an included editor by just pressing E 😮
looks like it! I actually hadn't heard of these.
you should cover the squirrel programming language.
thanks, I hadn't heard of this one!
I really like how for and while loops aren't language level. Means you could make your own
LOVE the argument hoisting
The underscore thing is klugey for sure
what do multiline anonymous functions look like? Do they require `return` or is it just the last line
seems like the last line of lambda functions are the returned value. See the map example. A mapper should return a value, but no return was written, so I would assume my theory is correct
as a matter of fact, he never showed us how to return from a normal function either, and I think it might be the same thing, for consistency. Like Rust, I would also assume you still can add the return keyword, for early returns for example
@@notkamui9749 that is actually different, you use `return` for a named function, and last exp for a lambda. But why, do you ask, well, because `return` inside a lambda allows you to return from the enclosing named function! This truly allows lambdas to function like the body of a control structure. In other languages, you can write your own "for" loop using a lambda, but you'd have no way to break/return from that iteration
re: 'underscore thing is klugey', the author appears to be considering using something else instead of _ for namespaces, as per his todo list on github.
Compiled Python! Awesome!
more importantly, statically typed
@@xybersurfer Agree!
I guess the only thing world needs, for leading language, is an easier way to catch undefined behavour in C++.
What is that font
I think this one was Monaco. But at some point I switched to FiraCode Mono, I struggle to pinpoint exactly when that was but I think it *might* have been after this video
@@codetothemoon Thank you
The Lobster language competes Cute Fish OS with curl.
What is the point of having a 'struct' that is immutable?
Same reason you'd have any immutable value - you know the value(s) when it is initialized, and you'd like to guarantee they won't change after that. Eliminates potential synchronization issues, opens the door to compile time optimizations, erroneous mutation of the fields, etc
@@codetothemoon I think you may have missed my point. While I agree that an immutable struct can be useful... Your example is one such case, but only one. An immutable struct is just an accumulation of constants. A struct can be used for far more cases then just that. Back in the olden days we used them for IO amount other uses. They can be very useful for database records which are notorious for needing changes and writing back to the database..
I see something about "this new programming language" i click . What can I say I'm simple man
I'm the same way... 😎
It's so funny when he says "this language has the inference you would expect from modern language, and even more !", ML languages have the same inference and they're 40 years old.
Not quite, they're based on "Hindley Milner" type inference which has the downside that inference breaks down if it can't infer generic types for ALL callers of a function.. and if it can, all those types need to go through that generic representation, potentially making things really slow. That's what you need type classes in Haskell for. Lobster can deal with wildly different types without a common super type or type class, and also be more efficient for each caller.
@@WoutervanOortmerssen I'm not sure to get it all. I looked up "Hindley Milner type system" and it seems really interestng. What you're saying is Lobster has another way of infering types, which is more efficient ? That makes me curious about it.
@Wouter van Oortmerssen could you talk more about Lobsters type system? Is it on the web site?
"If you squint, you feel like you're writing Haskel".... ... or Ruby! :)
true!
>Worked on Borderlands 2
Alright, here's my guru now
It seems that the second parameter of 'for' is not a real fn (15:15), but some kind of 'block'
for(3) i: print("1: {i}") // ok
def f1(i): print("2: {i}")
for(3,f1) // error: `)` expected, found `,`
so I believe such inline blocks (used everywhere in Lobster) are not real fns. And that is great of course, no need for real fns there and I hope the code is optimized and everything is inline (although I didn't study that yet).
All in all, the language is quite close to my ideal, maybe with some changes it can be.
btw how do you do this in Lobster?
def double(x): return 2*x
def apply(f,x): return f(x)
print(apply(double,3)) // can't use named function `double` as value
aha, I see...
let double = fn x: 2*x // , although can't print def'd fn
print(apply(double,3)) // 6 i.e. ok, although still can't do for(3,...) with such 'FUNCTION'
So it's basically rusty Python
> Or maybe cherry-pick the features you like and go seek them the out in other languages
*and implement them in your yet another language
Another language, and still the same barrier of entry with development environments.
Looks interesting
agreed
This must not be the one for me. After most of the features shown, I found myself asking "but why?"
Nope, I'm happy keeping Zig as my current hype language.
zig is not a hype language, it has curly brackets like its the 80s
@@terryriley6410 Spoken like a true web developer.
@@delphicdescant it's a joke. fyi indentation sensitive syntax dates back to the 60s.
also most of the "big names" in no-curly-brackets languages are not web-dev focused: Python, Haskell, F#
web development happens mainly in JavaScript and TypeScript, both have curly braces to denote scope
@@terryriley6410 Joke acknowledged. Really hard to tell what's supposed to be a joke on the internet in these post-irony times.
this language should replace python, which will be a great improvement in execution time
We have Mojo, also Nim exists. But we'll see.
The video is only focused on syntax, so I will focus my critique on syntax. There are a few things I like and dislike about the syntax, with one I absolutely despise.
The few things I like are the explicit auto-binding of class to functions with :: . I kinda like it. But I dont think Id allow it in a multi-contributor repo though.
I also like the alphabet-style lambdas. Very cool.
I dont really favour the implicit class auto-binding (without the ::). It’s cool though, but it allows method calls to be strewn all over the codebase. Not good for ergonomics.
Now to the dislikes.
I dislike the currying (actually currying in general). Makes it difficult for reading. Maybe I will get used to it. I hope.
The one I really despise is the implicit imports, because it will be very hard to figure out where the function came from, unless you have a tool to do so. I do like dependency injections, but not this level of implicity.
Overall, the things I dislike are the implicits, but in general it is still usable, since most of the things I dislike can be disabled at lint-time.
You lost em at the indentation. I don't know why but I simply cannot work like that, that's why I've never used python. I know it's weird but this kind of feature makes me very uncomfortable, maybe because my background is C, Pascal, Ada and Prolog.
I probably did! I personally enjoy indentation for scoping, but I can totally relate to the arguments against it
Probably because, or at least what I'm thinking anyway 🤔, is they always fail to tell you, for some ridiculous reason, when using a programming language that uses indentation for scoping, to never, ever mix tab indentation with space bar indentation in a language like python, where it expects consistent indentation types for it's scopes, unlike the C-like languages that use my least favorite thing that I think is time waster, curly braces to handle scopes.
Gosh darn, if I had known that python treats tab based, & space bar based indentation differently, & actually discourages the use tab based indentation anyway, that one detail in the indentation rules that's easy to overlook, that would have saved me from receiving the dreaded "indentation errors" that left me scratching my head, wondering, how? What did I do wrong, when this looks correct! I would have not gotten demoralized so fast when I was learning to code since I was 14 years old, & probably would have advanced far enough to create my own memory safe programming language, & maybe even my own os, wayyyy sooner, maybe even started coding for the Arduino as well at a younger age! 😅
@@codetothemoon I think the arguments against indentation for handling scopes are very silly, because they most, very likely overlook the fact, that you should never mix tab based indentation, with space based indentation in these types of programming languages, which makes me wonder 🤔, why on earth does tab based indentation have to be different from space based indentation, instead of making tab equal four space in python, or similar language? Would prevent all of the dreaded "indentation" errors, especially when programmers, are very used to using tabs & space in conjunction with one another while coding?
Anyway, to me, the only really valid reasoning to be against indentation for code scoping, can only be within the realm of personal preference/taste, & nothing more whatsoever.
C++ doesn't have structs the same way C# structs or Lobster structs work. In C++, structs are just classes where members are public by default.
What I meant is that Lobster has both structs and classes, not necessarily that they work the same way. I definitely could have worded that in a less ambiguous way!
the syntactic sugars of Ruby with the type inferencing of TypeScript? Wow, I'll be keeping my eye on this
but tbh I'm not the biggest fan of significant whitespace
I like python and this looks a lot like it, but why does it feel more like lua (haven't written any lua, so maybe I'm just crazy)? I still seem to prefer the idea of slowly moving to rust, it just seems to potentially hit a sweet spot of syntactic brevity vs specificity/intention (not to mention it makes like 0 efficiency tradeoff).
has nothing to do with lua
Lobster: 🙂
Lobster without limbs: 😳
you might have to walk me through this one :)
@@codetothemoon it's just the tail thing and the head
Kinda phallic
Please don't ban me off the channel or whatever, my dirty mind made stupid idea
I'm already sold 🎉
it's worth checking out at least!
No namespaces it seems? Import std just put the map in the current namespace. It's one of those small things Python does right that for some reason every other language seems to insist on doing wrong.
interesting language..
Still wondering how my best language would be structured...
(Definitely more towards a C/java mashup though...)
Oh cool they're releasing python 4
Very cool language! The title is misleading though as C already exists.
Glad you liked it!
12:45 That's a cool feature, but practically speaking, I don't like it. Sure, it saves a couple bytes in your binary, but as someone whose had to work in legacy systems where I'm not overly familiar with it's language, this kind of thing would throw me off so much. It's nice in the moment, and maybe for personal projects where you know you're one of the only people working on it, but for large code bases, I would not use this.
Enumerated parameters instead of giving them explicit names? If they were referenced by numbers it would make sense even if it is still a stupid feature, but using letters of the alphabet is just really dumb.
Struct fields are immutable but structs get passed by value doesn't seem right.
Interesting
agree 😎
lots of nim vibe in lobster
definitely!
Nim? 🤔
@@T1Oracle nim programming language
9:06 - Amazing feature. Although it's often best to make functions as explicit as possible, and it most likely increases compilation time
for a little bit of syntax sugar.
This is more powerful than syntax sugar, this is basically self building traits
@@Alguem387 Depends on how it works. If you have two unrelated classes that would obey the function's interface signature, would the compiler raise an error, or happily allow both classes to be used (the latter being what you'er saying).
I hope it's not the latter, because it will mean that you can accidentally use classes in context's that don't make sense
@@carlosmspk judging by the error message it looks for the property
@@Alguem387 Yeah, I agree, which I don't like very much. But either way, it's a opt-in feature, so I guess it's not really a bad thing
The compilation time increase will probably be miniscule though