Live data from Hacker News

Microfeatures I'd like to see in more languages

buttondown.email

91–100 of 539 posts

Re: Microfeatures I'd like to see in more languages

#91
One of the best truly micro features I've seen recently (can't remember which langauge unfortunately - it wasn't a mainstream one), is general binary literal syntax of the form:

    0x[de ad be ef 00]
So much nicer than the usual condensed format. And I think it'd be valid syntax in any language that allows binary integer literal.

Re: Microfeatures I'd like to see in more languages

#92
post #16

Earlier quoted context omitted.

At the moment, the only one I know for sure is Agda. I suspect java would work as well, not sure about golang unicode var naming.

play.golang wouldn't let me use figure (‒, U+2012), endash (–, U+2013) or emdash (—, U+2014) in a variable name directly. But then the spec[1] says that only code points characterised as "Letter", an underscore, or characterised as "Number, decimal digit" are valid. [1] https://go.dev/ref/spec#Identifiers

Coptic Small Letter Dialect-P Ni should work, looks like a hyphen.

Go Playground: https://go.dev/play/p/kxgOcEWsznz

https://www.compart.com/en/unicode/U+2CBB

Re: Microfeatures I'd like to see in more languages

#93
post #28

Earlier quoted context omitted.

Tail call optimization can get you that, too. If you've written Scheme and/or gone through SICP you might be familiar with this: you write a recursive function, with the recursive function call as the last thing the function does ('tail-recursion'), and the compiler/runtime is able to optimize those recursive calls out rather than consuming one stack frame of space per call ('tail call optimization'). Clojure has loo…

Interestingly, I almost prefer Clojure's `recur` semantically. Means you don't have to change the function name twice if you rename it, and it's hard to miss that you're recursing.

Those are cool properties. Another one is that you get a compilation error if your recursive call isn't in the tail position (and thus would actually grow the stack when you thought it didn't).

One thing I don't think you can do with loop/recur, though, is optimize more complicated bits of recursion than a single function that calls itself. I.e. imagine a recursive call pattern that goes like f -> g -> f -> g -> ...

(edit: I'm pretty sure this is why trampoline exists, though I've never really played with it... https://clojuredocs.org/clojure.core/trampoline)

Re: Microfeatures I'd like to see in more languages

#94
post #79

Negative array subscripts. So a[-1] means the last element of an array, a[-2] means the second last, and so on.

Any language that supports overriding the index operation should support this. You should be able to do this in C# with a struct with a backing array, for instance. If you're going to do this, use the word "Circular" in it, and I would also insist that if a has 4 elements, then a[0] == a[4] == a[8]. In other words, you always just take the (positive) index modulo the size of the area. Then a[-1] is the same as a[N-1]…

Where would the circular indexing like that be useful?

Re: Microfeatures I'd like to see in more languages

#95

Earlier quoted context omitted.

I don't get it, how are |> and <| any different from parentheses?

Chaining without nesting.

If you mean without closing parentheses, I think you can also do that in languages like Haskell with non-parenthetical function calls.

Re: Microfeatures I'd like to see in more languages

#96
post #82
post #32

Earlier quoted context omitted.

If you have constants repeated throughout the codebase, you can pull them into a constants file, and then you can go to that file, navigate to the definition of interest, and use your IDE of choice to find usages. You'll also be able to give these constants semantically significant names, and comment next to them providing derivations or citations. And of course, if it's a mistaken or outdated value, you can change i…

I'm in the same boat as GP. Typically, I grep such things when I am not familiar with the codebase, so I can't change where constants are defined, and I do not know where to find such a file.

For what it's worth when I dive into a new codebase, the first thing I do is try to guess what files exist and then find them and get a feel for structure. Constants are high in the list.

But there are many ways to skin a cat.

Re: Microfeatures I'd like to see in more languages

#97

Negative array subscripts. So a[-1] means the last element of an array, a[-2] means the second last, and so on.

That's for languages that can't define arrays with custom start/stop indexes. But those that have custom indexes they can very easily expand/implement as helper class (for example array.indexFromLast(1) which means array[Length(array)]. This way you can have best of both worlds.

Surely if your language has custom indexes / ranges `Length(array)` is completely broken and the language provides something like "Index`Last" you can hook on?

Because an array with indexes [3, 7) has length 4, but 4 is not the index of the last element.

Re: Microfeatures I'd like to see in more languages

#98

Php supports kebab-case variables: ${"variable-name"}=123; Isnt it beautiful?

How many languages support kebab case with any Unicode dash that isn't the ASCII one? :)

Agda does, but it also supports a plain ascii hyphen in identifiers. It allows operator characters inside identifiers and requires spaces around operators otherwise (as proposed in the article). So you can use x-y as an identifier:

    x-y : ℤ → ℤ → ℤ
    x-y x y = x - y
The Agda community also heavily uses unicode characters. I've even seen a unicode colon used for a custom syntax because the ascii colon was unavailable.

Re: Microfeatures I'd like to see in more languages

#99
post #42
post #4

My favorite is uniform function call syntax. In several languages (Nim, Koka, D, …), you can always write bar.foo(baz) instead of foo(bar, baz) and vice-versa. Another one from Nim is the implicit result variable. Instead of having to do this: func sum(nums: seq[int]): int = var result = 0 for num in nums: result += num return result you just do this: func sum(nums: seq[int]): int = for num in nums: result += num It…

and vice-versa Doesn't the reverse pollute the function namespace? If every obj.fun() can be written as fun(obj), doesn't that cause ambiguity with a previously imported global function fun()?

In Rust, it's still qualified by the type you're calling it on, which I assume is also the case in other languages.

Re: Microfeatures I'd like to see in more languages

#100
post #15

> Instead of writing 10000500, you can write 10_000_500, or 1_00_00_500 if you’re Indian. I hate this so much. It means I can't grep for a constant.

Out of interest, how often do you do this, and what are the semantics of the numbers you're grepping for? I literally can't remember a time I've ever tried to grep for a number.

I've done it for error codes but that was awfully cursed
Post reply on HN