Why make it complicated?
Why make it complicated?
Made with KolourPaint and screenshots from Kate (with the GitHub theme).
Why make it complicated?
Made with KolourPaint and screenshots from Kate (with the GitHub theme).
IT'S SHOWTIME I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE a GET TO THE CHOPPER a HERE IS MY INVITATION "ArnoldC is the best." ENOUGH TALK TALK TO THE HAND a YOU HAVE BEEN TERMINATED
The actual reason why let ... in syntax tends to not use C-style "type var" like syntax is because it's derived from the syntax type theory uses, and type theorists know about parameterised types. Generics, in C++ parlance, excuse my Haskell:
let foo :: Map Int String = mempty
We have an empty map, and it maps integers to Strings. We call it foo. Compare:
Map Int String foo = mempty
If nothing else, that's just awkward to read and while it may be grammatically unambiguous (a token is a name if it sits directly in front of =
) parser error messages are going to suck. Map<Int,String>
is also awkward but alas that's what we're stuck with in Rust because they reasoned that it would be cruel to put folks coming from C++ on angle bracket withdrawal. Also Rust has ML ancestry don't get me started on their type syntax.
Until now, I looked at let
and thought, "maybe they just felt like doing it that way".
Makes a lot more sense now.
There is also the thing where the compiler might mistake your c++ style variable declaration for a function, e.g.
String myfunction():
String myvariable();
Good, now invent a keyword for variables you don't want to declare the type. And now that you have a mix of keywords and identifiers on the same place, you can never update your language again.
Also, make the function declarations not use a keyword too, so you get the full C-style madness of code that changes meaning depending on what libraries you import.
Good, now invent a keyword for variables you don't want to declare the type.
auto
. Also in D, you only need const
if you don't want to specify a type for a constant, the compiler automatically inferres it to you.
Function declarations can be easily decyphered from context, no problem.
Maybe that's what the people developing spoken languages thought, while normalising conversations overdependent on context.
But hey, now we have another comedic tool in anime.
I don't understand how not using a keyword to define a function causes the meaning to change depending on imports. I've never run into an issue like that before. Can you give an example?
C++ has auto
, which determines the type automatically.
let a: &'static str
Rust is verbose, but C++ might still take the cake with its standard library templates. Especially when using fully-qualified type names...
auto a = ::std::make_shared<::std::basic_string<char, ::std::char_traits<char>, MyAllocator<char>>>();
A reference-counted shared pointer to a string of unspecified character encoding and using a non-default memory allocator.
fully qualified type names make any language awful.
Here's the same example in rust:
let a = std::rc::Rc::new(std::vec::Vec<u8, MyAllocator>::new());
I believe u8 also comes from a module, so it would be something like std::u8::u8
, but I'm not sure.
I don't understand why verbose is bad. Verbose is maintainable.
You're encoding more information in the typescript one. You're saying it's a string that will get updated.
You aren't though. In most languages that use the latter declaration you would prefix the declaration with final or const or the like to specify it won't be updated.
C# has const string a = "Hello, World";
var in js is legacy, and default should be let, but changing that would break everything
Because sometimes that let
can be replaced by other things like const
. Which can be managed statically by the machine and not by my (imperfect) ability to know if it's mutated or not
I think you can do const thing = ... as const
to lock down the mutation?
So is let
in some languages. In Rust, you have to constantly opt out from immutability with let mut
, which makes writing more procedural code feel like you're fighting with the compiler, and otherwise I don't really see the rationale behind full functional coding. I only had a bug caused only once by unwanted mutation, the hardest part fixing it was to learn the proper use of my debugger tool.
Ok but, in the second example you typically just put final or const in front of the type to denote immutability. I still don't see the advantage to the first declaration.
oh for sure, but I think that's the rarer case for language implementions. Having a consistent structure with alternative keywords in static positions is just easier to develop an AST for. Personally my favorite language doesn't even allow for const values (except by convention) so it's really just a matter of preference
Not to short-circuit the joke, but in this case, it's because the valid JavaScript version is...
js
let a
...and one of TypeScript's main design goals is to be a superset of JavaScript, that only adds syntax, and doesn't re-write it.
Beyond that, it's probably a case of some new language just using what the designer is familiar with.
I've always wondered where all this 'let' business started
It's commonly used in math to declare variables so I assume programming languages borrowed it from there.
More specifically, they're borrowing the more mathematical meaning of variables, where if you say x equals 5, you can't later say x is 6, and where a statement like "x = x + 1" is nonsense. Using "let" means you're setting the value once and that's what it's going to remain as long as it exists, while "var" variables can be changed later. Functional languages, which are usually made by very math-y people, will often protest the way programmers use operators by saying that =
is strictly for equality and variable assignment is :=
instead of ==
and =
in most C-style languages.
BASIC uses (used?) it to declare variables. (I don't know if earlier languages did.)
Not that that's a reason for other languages to copy it.
More than you'd ever want to know: https://en.m.wikipedia.org/wiki/Let_expression
I doubted you until I got about halfway through this whole page. I concede tho--you are most correct lol Still a decent read and for that I thank you
Can we talk about PHP functions with typehints too?
public static function foo(): string {
Practically every other language with similar syntax does this instead:
public static string foo() {
Rust and TypeScript use the return-type-at-the-end convention as well.
TypeScript doesn't need the "function" keyword for a method in an object or on a class though.
const foo = { bar(): string { ... } }
which I assume is doable because the syntax is unambiguous.
PHP's object orientation is similar to languages like Java and C#, which is what I was comparing to.
Python too.
TIL PHP has statics.
Also, does PHP actually enforce the type declarations? I'd assume it would but knowing PHP...
It enforces scalar types (string, int, etc) at runtime if you enable strict mode. There's also static analysis tools like PHPStan and Psalm that will flag issues at build time.
JavaScript (Typescript for the type part) and python, the most popular scripting languages, use the same order as PHP.
It's usually compiled languages that do the other one.
TypeScript doesn't need the "function" keyword for a method in an object or on a class though.
const foo = { bar(): string { ... } }
which I assume is doable because the syntax is unambiguous.
In PHP's case, the method syntax should also be unambiguous.
First time i used let it was to inline variable declaration with assignment . Can’t remember the language.