4 ms·
If you think your numeric type everywhere may change down the road, you could split out the operation and e.g. define let add = (+) and sub = (-) ... etc. and u
by silentbicycle 18y ago
If you think your numeric type everywhere may change down the road, you could split out the operation and e.g. define let add = (+) and sub = (-) ... etc. and use those in your code, so you will only need to change them in one place, should you change your numeric type. Abstract out the operation. (Then you're back to using prefix notation.) Or, change it once, and let the compiler show you everywhere else it needs to be fixed.
Haskell's type classes are a better overall solution for numeric types, of course. Not having a parallel to Haskell's deriving show in the OCaml standard is also annoying, but it's available elsewhere. (See: http://alan.petitepomme.net/cwn/2008.07.08.html#4 http://alan.petitepomme.net/cwn/2008.07.08.html#4)
Still, most (though not all) numeric operations fit under either exact (int, bignum, ratio) or inexact (floats) without much ambiguity.
- lisper 18y ago> If you think your numeric type everywhere may change down the road If programmers were always that foresightful, programming in general would be a whole lot easier. > Or, change it once, and let the compiler show you everywhere else it needs to be fixed. I find this downright perverse. If a compiler is smart enough to know what needs to be fixed then it should just go ahead and fix it instead of fobbing the job off onto the programmer.
- silentbicycle 18y ago> If programmers were always that foresightful, programming in general would be a whole lot easier. Agreed. That's what encapsulation is for, though. When code isn't separated into sections with defined borders, it tends to grow entangled and hard to change. For a real (albeit simple) example, something I'm working on has several instances of an ordered collection (with a few irrelevant quirks). I presently have the type declared (once) as type 'a coll = 'a list ref (* pointer to a Lisp-style list *) for the obligatory quick-but-inefficient scaffolding, and wrote a few one-or-two-line functions inserting, checking for membership, and the like. (They're just aliases to existing funs in the List module.) I expect to swap out the implementation so I can compare e.g. skiplist, RB Tree, hash table, etc., performance later. Given the constraints on the problem, none seems obviously better (though I'm betting on skiplists here, space reasons). 'a coll is used throughout the program, but changing that line and those few short functions will replace it everywhere (and it will notify me if I miss something). 'a coll is also polymorphic on another type, because the whole module is a functor. (It's for a language-agnostic source code analysis tool.) This structuring is nothing specific to OCaml, though; data encapsulation is main idea of chapter 2 in SICP. (http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-13.html#%_chap_2 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-13.html...) Likewise, in an OO language I could swap in different collections subclassed from Collection, or just with the relevant methods, depending on if the OO implementation used class-based or structural/"duck typing" polymorphism. That's the same overall result as the above, though by slightly different means. > If a compiler is smart enough to know what needs to be fixed then it should just go ahead and fix it instead of fobbing the job off onto the programmer. OCaml's H-M type system doesn't try to guess whether you meant all references to x to be type A or type B, it just tells you that they aren't internally consistent. It would be guessing. (How would the compiler know if you're gradually changing from A to B or B to A from just a snapshot, anyway? That's analogous to the Heisenberg uncertainty principle.)
- lisper 18y ago> OCaml's H-M type system doesn't try to guess whether you meant all references to x to be type A or type B, it just tells you that they aren't internally consistent. No, it doesn't tell you that. It tells you that they are internally inconsistent WITH RESPECT TO OCAML's SEMANTICS. They are not internally inconsistent in any absolute sense, as evidenced by the fact that I can write (+ x y) in Lisp and it will produce a sensible result whether x and y are integers, floats, rationals, complex numbers, or any combination of the above. This is an existence proof that compilers can figure these things out. Hence, any compiler that doesn't figure these things out and places this burden back on the programmer is deficient. OCAML's design requires its compiler to be deficient in this way, which makes OCAML IMHO badly broken. OCAML, in essence, requires the programmer to engage in premature optimization of arithmetic primitives. The result is, unsurprisingly, a lot of unnecessary work when certain kinds of changes need to be made. Maybe you can "get used to" this kind of pain, but to me that seems to be missing the point rather badly.
- silentbicycle 18y agoYes, "...aren't internally consistent within OCaml's type system.". What does your Lisp implementation (SBCL?) do with (+ x y) when x is a float and y is a bignum? Is there an implicit conversion at run-time or compile-time? (I don't have SBCL at the moment, it's not available for either of the platforms I develop on. Sigh.) If so, that's a fundamentally different result than OCaml, which is deliberately avoiding implicit conversions under all circumstances. I'm not saying that's an inherently better choice than Lisp's (it can be annoying), but this thread was initially about making Lisp faster, and that's part of how you do it. Adding optional type inference, whether by H-M or something more flexible when mixed with non-statically-typed code (which seems like the real trick, but I'm still learning how type systems are implemented) to e.g. Scheme would be a great compromise. I believe MzScheme has had some research along these lines (MrSpidey: http://download.plt-scheme.org/doc/103p1/html/mrspidey/node2.htm http://download.plt-scheme.org/doc/103p1/html/mrspidey/node2...), but it's not available for R5RS yet. I like OCaml's strict type system more for how it helps with testing/debugging than the major optimizations it brings, really, but the speed is nice. Also, OCaml is not an acronym (but I'm guessing that was from autocomplete in Emacs).