5 ms·
There is no easy way around this if you really want a collection which is heterogenous, but often, you would just cook up a struct/record-like object for these
by jlouis 12y ago
There is no easy way around this if you really want a collection which is heterogenous, but often, you would just cook up a struct/record-like object for these things.
Trading off easy heterogenous lists buys you a better type checker, more static knowledge, faster programs and so on. It also has the advantage that mapping data into the system can be done safely. The price is that self-describing data (JSON, Transit, Msgpack, ...) is more unwieldy to work with - but a little combinator library, scrap-your-boilerplate-generics, or a reflective code generator goes a long way to solve that problem:
- OCaml: Yojson.Basic.Util
- Haskell: Generics, Rank2 polymorphism
- Go: JSON unmarshalling
are all examples of how to handle that problem.
- kazinator 12y agoYou seem to be implying that the generic lists shown in Python or Lisp are somehow unsafe. They must be since if we throw them away, or wrap them in some clumsy structs/records, we can "buy" safety. Even if that is the case, we cannot sell Haskell as some kind of semantically rich language for doing cutting edge research, when coding up basic things like this is a struggle. If I have to cook up things with structures, I might as well use C. Here is another simple problem: divide two integers so that the result has integer type when the numbers divide evenly, otherwise rational type.
- AnimalMuppet 12y agoI am by no means an expert, but I think that Haskell handles your second problem without blinking (because integer is a subtype of rational). For your first problem, C doesn't help in the general case. If I got a JSON package, I don't know at compile time what the types are going to be, so I don't know how to lay out the struct. If I don't know anything about the types, the only things I can (safely) do are put them in untyped collections or convert them to strings. I can't add them - they might not be numeric. I can't convert them to uppercase - they might not be strings. (I can do all those things if you're going to return a Maybe - and maybe that's the right approach if you got a JSON package over the wire.)
- kazinator 12y agoPardon me, I should have said "ratio" rather than "rational". (definition: rationals are partitioned into ratios and integers).
- edwardkmett 12y agoOn the other hand, here's a problem. Extend your numeric type tower to handle whatever new numeric types I come up with in an internally consistent manner. In haskell I have number types for things that automatically compute derivatives. I have number types for functions that go to number types so all vector spaces work like numbers as well. I have number types for arbitrary precision floating point numbers, and I can build these things on top of each other. It is a trade-off. We give up a bit of one thing to get something else. You can take either side of the deal. I'd argue that the weight of benefit is on the side where we don't have a magic type tower to reason about, but it is a perfectly reasonable stance to say that the thing you want is more important to you. On the other hand, I can turn around and argue that if what I really want is an ad hoc tower of numeric types I can just make a type for that and work inside it. data Number = Int Int | Rational Rational | Double Double | Complex (Complex Double) | ... instance Num Number Now I can opt into your model. Can you opt into mine?
- GregBuchholz 12y ago>Can you opt into mine? In Python, not only can you "opt in" to those features (in a completely natural way) but those features already exist in the form of highly popular libraries: NumPy - http://www.numpy.org/ http://www.numpy.org/ SymPy - http://www.sympygamma.com/input/?i=diff%28x**2%29 http://www.sympygamma.com/input/?i=diff%28x**2%29 mpmath - http://mpmath.org/ http://mpmath.org/ ...and the story is similar with Common Lisp, whose generic functions dispatch on function parameter type (just like Haskell allows with type classes), allowing you to create libraries for vector arithmetic, symbolic algebra, and arbitrary precision floating point math, again in a completely natural style. The best forms of language advocacy probably involve showing the great things you've done with a language and forgetting about comparisons to the competition. Build it, and they will come.
- dllthomas 12y ago"The best forms of language advocacy probably involve showing the great things you've done with a language and forgetting about comparisons to the competition." Great things the parent has done with the language: https://www.youtube.com/watch?v=cefnmjtAolY https://www.youtube.com/watch?v=cefnmjtAolY
- the_af 12y agoI don't see that they're a struggle. They are more verbose than with Python or Lisp, sure, but you gain something in return. On the other hand, you seldom find yourself needing to write those heterogeneous lists in Haskell, so what's the actual problem?
- dllthomas 12y ago"divide two integers so that the result has integer type when the numbers divide evenly, otherwise rational type." kazinatorDiv x y = case x `divMod` y of (q, 0) -> Left q _ -> Right (x % y)