The let/var declarations for constants/variables is much better than implicit declaration, which silently hides typos and necessitates ugly global/nonlocal declarations. (Mojo offers this improvement too.)
I don't know for sure, but it seems like it's embraced block arguments comparable to how Ruby or SmallTalk does it. So you can add your own control flow, container visitors, etc. I think of this as another syntax for passing a lambda function as an argument, and I'm curious if Lobster's optimizer flattens it to a basic block when possible.
I think I'll try to learn more about it. I wonder if the name is a nod to Accelerando.
The name does not refer to anything in particular :)
> Features have been picked for their suitability in a game programming language
Would be fun to see some basic games like tetris, pong etc in Lobster in case anyone has an example floating round?
It comes with a tiny minecraft clone in < 100 lines of Lobster.
Agreed it could use more actual game examples. I've written a ton of game prototypes in it, and some could do with open sourcing, just haven't gotten around to it.
It brings the joy back to graphics and game programming.
I noticed that Lobster, like many other languages, does not use the C style for-loop syntax, `for (int i = 0; i < m; i++): print(i);`. Could you say why that is? I have been writing Python for many years but still miss that C syntax. Initiating `i` right before every loop feels clunky to me.
The syntax comes from the observation that even in C-like languages, 99% of the time I want to iterate over the range (0..m-1), so that's what it is optimized for.
I don't enjoy writing the same boilerplate over and over. Moreover, because it is so verbose, it is hard to spot `for (int i = 0; i <= m; i++): print(i);` being a special kind of loop since it looks so similar to the common `<` case. I'd rather that looks entirely different to alert me we're also iterating over the bound.
I am not sure what you mean by "Initiating `i` right before every loop"
Now that's a strong opinion, (weakly held - as a language can't be judged based on this design decision). But it does sour my interest a bit.
I think we'd be better off if text editors just had option of representing braces and such as consistent indentation. Block delimiting tokens should optionally have semantics of non directly printable characters like new line or tab.
Even Allman versus K&R or tabs versus spaces are huge battles, without even going into significant white space.
I never figured it out by the way - just bought a really long LAN cable.
Ever since Go got big, though, everyone else is discovering how fantastically nice they are, and that’s a good thing.
Now, when you paste code and things are wrong, an auto formatter cleans it up for you. Before, you'd just end up with an unreadable codebase.
It's definitely an odd choice to make now.
If you grab that version and unpack it and look at /OChangelog then it seems to date back until at least 1989, same as Python itself.
That was for C source, of course. I expect there were pre-GNU indent variants, perhaps posted on comp.sources.unix and maybe some commercial things as part of very expensive compiler packages.
I would say that running autoformatters in any kind of routine way was pretty rare. EDIT: but I think ascribing the language design to commonality or not is probably ahistorical. Even today it's a rather passionate debate. And even at the time, Lisp - the poster child of copy-paste friendly PLangs - was routinely autoformatted within Emacs', but that was not enough for people to not find Lisp code "ugly".
Convert your YaML into JSON and save it in your YaML file. There is probably an online converter, but writing one in your language of choice should be less than ten lines of code.
Do the same YaML→JSON for the “source” configuration you want to copy from, and copy-paste the parts you want. Leave them as JSON.
Complaining about Python's significant whitespace, I get it. I don't mind it personally, but it's obligatory and you can't overcome it (unless you do `coding: with_braces` tricks, of course). But why one would complain about YaML's whitespace? It is not obligatory.
some_key:
attr1: val1
attr2: 12312
is equivalent to {some_key: {attr1: val1, attr2: 12312}}
is equivalent to {"some_key": {"attr1": "val1", "attr2": 12312}}
is equivalent to {"some_key": {
"attr1":
"val1", "attr2": 12312
}
}
and they're all valid YaML (and on the plus side you can leave dangling commas at the end of sequences, but it won't be valid JSON anymore).The problem (as felt by me and also as identified by the person you replied to) is that you can't copy-paste/munge some stuff into the right spot and then just let the formatter to fix the indentation. It's not a problem that the format "at rest" has whatever certain indentation to be correct, its that while being actively editing your formatter cannot automatically set the correct indentation.
The flow that you're talking about of converting yaml to json and then putting it into yaml could work in some cases but thats very much a kludge. It will have numerous bad side effects unavoidable, including that it would discard comments in the middle since JSON doesn't allow for comments at all, theres no timestamps in JSON, there's no octal numbers, etc.
That problem I undestand, and that is why I suggested to convert both into JSON —or YaML with default_flow_style=True which would preserve datetimes and other non-JSON stuff— and copy-paste without the hassle of having to indent/unindent correctly. Of course that doesn't help with copying comments. That would need extra copy-paste operations, but still one hasn't the hassle of significant whitespace. The following is also valid YaML:
{"some_key": {
"attr1":
# an intermittent comment
"val1", "attr2": 12312 # more comments!
}
}Whenever I come across a json config file, I kind of despair a little and start poking at the code in hopes there are comments about what the config means.
Who knows. Maybe some new fun language will pop up that's hard to write for humans, but easy to write for AI (because it can work in millisecond loop with language server, think borrow checker to the moon) and also exceedingly easy to read for humans. Because humans will, I think stil for a long time, need to debug ever shrinking corner cases where AI generated something subtly but spectacularly wrong.
"Dr. Grubbs, what inspired the language name"
"A Hooker down by the docks"
"WHAT?!?"
"Yes, I went to her lonely one Friday, she only cost five dollars. Next day I had a terrible itch and realized she'd given me crabs. So I confronted her the next day and asked why she had done this to me. 'What do you expect for five dollars, lobster?' "
The Lobster Programming Language - https://news.ycombinator.com/item?id=44051841 - May 2025 (6 comments)
The Lobster Programming Language - https://news.ycombinator.com/item?id=31453822 - May 2022 (14 comments)
The Lobster Programming Language - https://news.ycombinator.com/item?id=25498005 - Dec 2020 (4 comments)
The Lobster Programming Language - https://news.ycombinator.com/item?id=19567160 - April 2019 (164 comments)
The Lobster Programming Language - https://news.ycombinator.com/item?id=15557060 - Oct 2017 (2 comments)
Admittedly it’s just a first impression
imho, I don't consider Type-inference as a good thing when it happens from 50 lines ahead/below. How would regular people follow along?
Good case
x = "hello" // infer type as string - good thing.
Bad case
var/declare x;
50 lines later
if (....)
x = "world" // infer type as string - this is badvar/declare x;
25 lines later
call f(x); // ** Reader has no idea what x is ... even though compiler has **
25 lines later
if (....)
x = "world" // infer type as string - this is bad let i = 1;
let j = 1;
print!("i: {:?}\n", !i);
print!("j: {:?}\n", !j);
// pretend there's a lot of code here
// spooky action at a distance
let v = vec![1, 2, 3];
v[i];
You might think those two print statements would print the same value. They do not.With such a focus, be nice to have a few more OpenGL examples. Took a bit of looking, yet found a longer example for a 2D shooter. https://aardappel.github.io/lobster/shooter_tutorial.html
However, the real test, from personal perspective, especially with a custom framework for shaders, would be implementing one of the medium difficulty LearnOpenGL 3D examples, such as the Multiple Lights example. https://learnopengl.com/Lighting/Multiple-lights
With how much goes wrong with OpenGL and shader development, wary of delving very much into an OpenGL centric language, and then finding out there's a bunch of gotchas in the part that tends to be desirable (3D rendering). "Whoops, one of a zillion hidden flags doesn't get set properly for some reason."
Texture loading seems like its there, and it says it actually uses "stb_image.h" internally. Plus, it apparently does cubemaps.
Lights seem implemented, although not sure what that does "sets up a light at the given position for this frame."
Model Loading is also another, from the built-ins it looks like it does .ply and .iqm? (Inter-Quake Model) files.
Matrice math has a few although seems like a LookAt and Perspective matrix creator in the 4x4 category would be needed that return a matrix you can apply to a shader uniform. gl.perspective looks weird, just says "changes from 2D mode (default) to 3D right handed perspective mode"
Either way, looks cool, would just like to have more examples in the target demographic, OpenGL game development. Even if they're simple. That's part of why the LearnOpenGL examples are so useful. Simple. Implementing even a significant subset would go along way toward selling me on game development in an unknown language.
The repo comes with a LOT of graphical samples (in the "samples" dir).
The lights are more of standard way of passing them to the shader (see the phong shader implementation).
Matrices are a bit of a weak spot since its all implicit (which is convenient, but not powerful). There are also classes for direct use of matrices though.
Not seeing a phong example in the samples dir. "pendulum.lobster", "physics_boxes.lobster" Only reference to "phong" brought back in a search was milen-prg's comment on Aug 7, 2023 about using the phong shader in the "cgtest.lobster" example.
There's already bindings for Box2D in the "ph" namespace.
tines•5mo ago
Also, is there any kind of sophisticated pattern matching? I feel like for me a language without pattern matching is a non-starter these days.
Aardappel•5mo ago
I am sure it has some limitations, but it is pretty powerful, it can even do things C++ can't, like have a type error in a branch that in the current specialization is never executed doesn't count as a type error :)
There's no FPL style pattern matching. It can do a switch case on types (the various subclasses of a base class) but only 1 level, i.e. can't match against type of members. That could still be added, just personally rarely have use for it.
tines•5mo ago
I’ve struggled with my feelings on this even to the extent that C++ allows it, because while it is flexible, it can also hide errors in libraries that will only blow up when used in very specific ways.
Aardappel•5mo ago