News for hackers. Stuff that matters.
Re:Go and Simplicity Debt Redux by alkonaut on Monday June 19, 2017 @02:51AM (#14585013)
The only type I'd make (if it wasn't in the standard library) is the regular Option<T>. If I have an instance of Option<T> and the method takes a T, then I'd have to check and unwrap it. I can't see the need for creating multiple structs assuming you can nest the Option<Option<T>> when required (and heap allocation is OK)? Perhaps I misunderstood something.

If I have an instance of Option<Option<T>> then I'd have to unwrap it more than once. However, if the language has no concept of such automatic unwrapping, the chance that you would ever end up with a nested option is pretty slim. Basically, the monadic type use of these is an effect of the language doing that, not the other way. In e.g. C# where I use option types extensively I'm yet to see a wrapped one. In F# it's different.

In C# there is a feature in which nullables (e.g. int? and int?? or int???) actually work similarly because there are "lifted operators" which sort of half-achieve this, e.g.

   int? x = 10;
   int? y = 20;
   int? z = x + y;
but to be honest this to me feels mostly quirky because it doesn't extend to much else in the language.
Re:Go and Simplicity Debt Redux by catnaroek on Monday June 19, 2017 @03:06AM (#14585072)
> Basically, the monadic type use of these is an effect of the language doing that, not the other way. In e.g. C# where I use option types extensively I'm yet to see a wrapped one.

And C# pays dearly for it. Why doesn't C# have anything like C++'s <algorithm>, or Rust's composable iterators, or Haskell's plethora of composable abstractions (foldables, traversables, lenses, etc.)?

> In C# there is a feature in which (...) but to be honest this to me feels mostly quirky because it doesn't extend to much else in the language.

Agreed. Hardcoded special cases are always a bad idea.

---

Sorry, HN won't allow me to make a new post because “I'm submitting too fast”, so here goes my reply:

C++ has a finer-grained hierarchy of iterator concepts:

(0) InputIterators correspond to C# IEnumerators.

(1) OutputIterators allow you to write to the sequence's current element.

(2) ForwardIterators allow you to dereference the current element arbitrarily many times before moving on to the next.

(3) BidirectionalIterators allow you to move both forward and backwards in the sequence of elements.

(4) RandomAccessIterators allow you to skip arbitrarily many positions in the sequence of elements in constant time.

And there are algorithms defined in terms of these refined iterator concepts.

Re:Go and Simplicity Debt Redux by alkonaut on Monday June 19, 2017 @03:28AM (#14585152)
> Why doesn't C# have anything like C++'s <algorithm>, or Rust's composable iterators, or Haskell's plethora of composable abstractions (foldables, traversables, lenses, etc.)?

I'm not very familiar with the details of Rust iterators yet, but there isn't much I'm missing from Linq at least yet (apart from the cost control available in Rust and C++ that it's pretty natural is omitted from C# where it's natural that operations such as iteration can heap allocate).

What is the difference between <algorithms> and the similar Linq (or rather the enumerable extensions enabling linq)?