4 ms·
This one is kind of interesting: "Params: Function parameters must be named, but no need to repeat yourself, if the argument is named the same as the parameter
by ianbicking 5y ago
This one is kind of interesting:
"Params: Function parameters must be named, but no need to repeat yourself, if the argument is named the same as the parameter (i.e. keyword arguments can be omitted). Inspired by JS object params, and Ruby."
I've grown fairly fond of JS implicitly named object parameters, and I always liked Smalltalk's named(-ish) parameters, and this seems like an interesting compromise. I'm not actually sure how Ruby works in this case? I thought its parameters were fairly normal. Are there other languages that do this?
But in the case of one-parameter functions this seems unnecessary, the function name often makes it clear exactly what the first parameter is. And if you are going to support Subject-Verb-Object phrasing (as suggested later) then the Subject is another implicit parameter that probably doesn't need naming.
Maybe another approach is that all functions take one unnamed argument, and there are structs with named members for any case when that single argument needs to contain more than one value. Which starts to feel like JS/TypeScript. The static typing to support this in TypeScript feels really complex to me (it's unclear if the language described uses static types).
- rwmj 5y agoOCaml gets all of this right already. Labels are optional (which is IMO better than the article suggestion). You can abbreviate to only the label if the parameter variable is the same as the label. You can omit the label for labelled parameters if you want, they just become unnamed positional parameters. And of course the main thing is type safety to help you get parameters right in many cases. https://ocaml.org/manual/lablexamples.html https://ocaml.org/manual/lablexamples.html https://dev.realworldocaml.org/variables-and-functions.html https://dev.realworldocaml.org/variables-and-functions.html
- dan-robertson 5y ago(For others, labels are optional in three senses: not all parameters need to be labelled, the compiler can emit a warning if a label is omitted but you may want this to be an error instead, and there are optional labelled arguments which may be omitted entirely in some cases. Labels are not optional in that the type system is unwilling to convert between labelled/unlabelled or optional/omitted/required parameters and the compiler mostly won’t add hidden coercions between these types) A common case where the trivial-value syntactic sugar fails looks like: foo ~some_descriptive_label:t.some_descriptive_label bar ~something:!something Or baz ~the_option:config.the_option (Why not just pass the config? Two reasons: it is nice to have the interface being explicit about what data is needed, and the function may come from a module that cannot depend on the definition of the config type.)
- int_19h 5y agoThe ability to treat named arguments as unnamed is not necessarily a feature - it's too easy for the caller to mistakenly pass the wrong thing without a label, and it also makes it that much harder for the API owner to version it in the future. Python adopted a special syntax for named-only arguments for these reasons.
- stickfigure 5y agoI'm surprisingly happy with IntelliJ / Java's behavior. Java is all positional parameters, but anytime the arguments aren't obvious, IntelliJ shows the parameter name with subtle syntax highlighting. It feels like the best of both worlds. Completely random example, notice the 'limit': https://monosnap.com/file/FU6QjZ6Y4b7CNmBBBZoUQlpO8YTXsR https://monosnap.com/file/FU6QjZ6Y4b7CNmBBBZoUQlpO8YTXsR
- megapoliss 5y agoIt sound like java is not usable without the state-of-art IDE.
- kaba0 5y agoNo, it means that tools can be made to improve the developer experience…
- megapoliss 5y agoBut programming language itself is a tool. And, you need one tool to improve the other, that imply your tool (programming language) is not good enough. IMO, the only reason why java is still in use - superb IDE and tooling, that compensate terrible language design.
- stickfigure 5y agoYou've got it quite backwards. The superb IDE works synergistically with the language design to create an overall superior experience. Poor language design (undecideable edge cases, dynamic and unpredictable meanings) makes it impossible to create a satisfying IDE experience. If you're using vim or emacs to write code, you're wasting your employer's time. A good IDE makes you more productive.
- ianbicking 5y agoA ton of features on this list really require an IDE or rich program representation, or _something_ that's not just plain text. For instance using content hashes to refer to functions is only reasonable with IDE tooling support.
- sweeneyrod 5y agoI believe Ruby and OCaml have both anonymous positional arguments and keyword arguments with punning (i.e. `f ~arg` expands to `f ~arg:arg` in OCaml).
- CuriousSkeptic 5y agoOn your last point I’ve been toying with the idea of having even the function it self folded into that struct the struct defines the unbound inputs ad well as mapping those to different named outputs one interesting aspect to play around with is to then have commutative, and associative, application/evaluation operation where structs (or environments really) are merged and evaluated by binding what can be bound say (a,b:1+a)(b,a:1,c:a+b,d:2) would evaluate to (a:1,b:2,c:3,d:2) not saying its a good idea - kind of falls down on scoping - bu could be an interesting toy.
- ianbicking 5y agoThis makes me think about some sort of exec-with-dynamic-scope approach to functions, like: func = { b = 1 + a } result = func { a = 1 c = a + b d = 3 } Where func {...} (two adjacent blocks) is like a composition and merges the two blocks. "=" has the mathematical meaning, not assignment but a statement of equality. The parameters are just the free variables, e.g. func has a parameter of a. Are external routines or functions also parameters? I'm inclined to say yes, and that it's interesting to treat them as such. This is all very Mathematica/Wolfram-like, with concrete expressions with undefined terms, different than functions that are executed. The result has no real sense of order, and so it implicitly has to be purely functional. I can imagine using this to build things-that-execute, where this code doesn't execute but defines an execution (like tensorflow). Or there's some outside layer that creates streams of input, and the "execution" is how it responds to those streams. That outside layer is where all the system integration happens. It would work well with React-style unidirectional data flow. But I think for any practical program you'd have to live in both worlds.
- mhink 5y ago> I've grown fairly fond of JS implicitly named object parameters, and I always liked Smalltalk's named(-ish) parameters, and this seems like an interesting compromise. I'm not actually sure how Ruby works in this case? I thought its parameters were fairly normal. Are there other languages that do this? Ruby allows keyword arguments, which are very similar to object parameters in Javascript: # ruby def add(a, b, *args, x:, y:, **kwargs) puts a.to_s puts b.to_s puts args.to_s puts x.to_s puts y.to_s puts kwargs.to_s end add(1, 2, 3, 4, y: 'bar', x: 'foo', z: 'quux') # => 1 # => 2 # => [3, 4] # => foo # => bar # => {:z => 'quux'} there are also 'splats', which are pretty much the same as array/object spreading in JS: # ruby positional_args = [1,2,3,4] keyword_args = { :x => 'foo', :y => 'bar', :z => 'quux' } add(*positional_args, **keyword_args) # => (same output as previous example) One thing that's missing in Ruby (that I quite like in JS) is the ability to rename keyword arguments in the named parameter list, like: // javascript const example = ({ max: maxNum = 123 }) => { /* ... */ }; # ruby def example(max: 123) max_num = max # can't do this in the parameter list # ... end Honestly, this limitation is just about the only thing I think is missing from Ruby's parameter-list syntax. > But in the case of one-parameter functions this seems unnecessary, the function name often makes it clear exactly what the first parameter is. And if you are going to support Subject-Verb-Object phrasing (as suggested later) then the Subject is another implicit parameter that probably doesn't need naming. Maybe there could be a special sigil for positional arguments? I like the idea of gently discouraging them, but still making them possible. Maybe something like // hypothetical language function singleArgFunction(@arg0: number) { /* ... */ } function mixedArgFunction(@arg0: number, foo: string, bar: string) { /* ... */ } function standardFunction(alfa: number, bravo: string) {/* ... */} singleArgFunction(0); mixedArgFunction(1, foo: 'hello', bar: 'world'); standardFunction(alfa: 123, bravo: 'abc');
- KarlKemp 5y agoruby 3.1 added the feature OP is quoting. If you have local variables x and y and the method definition def doit(:x, :y) you can just call it with, IIRC: doit(x:, y:) instead of doit(x: x, y: y) as was needed before.
- redbar0n 5y agoGood suggestions for improvement. The latest Ruby version works as described in the «keyword arguments can be omitted» link. The dream language is gradually static typed. Like TS, but the type system and inference would ideally be more like OCaml or ReScript. Hopefully avoiding some of the complexity of TS, and gaining more soundness.