Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Functional programming beyond Haskell

Name: Anonymous 2015-02-20 8:36

We have all learned functional programming in Haskell, but there are more functional languages like Lisp, Scheme, ML, and Clean.

Why should we even bother to look further than Haskell?

- You want your programs to run faster.
- Monads drive you mad (what are they anyway? warm fuzzy things?).
- You need objects.
- You sometimes need a more powerful module system.
http://www.cs.uu.nl/wiki/pub/Stc/BeyondFunctionalProgrammingInHaskell:AnIntroductionToOCaml/ocaml.pdf

Name: Anonymous 2015-02-27 21:59

>>74,76
It really fucking depends man. Wasting memory is wasting cache -> wasting time. GHC can be intelligent about when to compute vs. when to memoize, but OCaml can be intelligent about when to defer/cache computation. Neither seem to do a super great job of these things. You don't want the lazy default if you care about latency.

>>78
Lazy vs. eager doesn't divide functional and imperative programming. What are you smoking?

>>80
Can't argue with this, even the OCaml jab. Not sure why you would even tolerate a broken numeric tower, but whatever floats your boat.

Name: Anonymous 2015-02-27 22:12

>>81
I don't get it. OCaml's numbers are all clearly defined. Is this to do with (+.) : float -> float?

Name: Anonymous 2015-02-27 22:22

Also I think lazy/imperative is related to some recent-ish thread in which the topic was mentioned, in essence drawing some parallel between lazy being a lot more composable (in the spirit of FP) than strict, with the example of map factorial [1..100] |> take 3 - lazy only performs factorial 3 times while both strict and imperative have the same problem of 100 factorials.

Name: Anonymous 2015-02-28 0:26

I think Perl 6 gets lazy right. It's very easy to be strict.

Name: Anonymous 2015-02-28 3:36

>>82
maybe he thinks that's a numeric tower. but ocaml's built-in numerics are all completely orthogonal up to explicit conversions.

Name: Anonymous 2015-02-28 9:58

>>81
There are no imperative languages with lazy-by-default evaluation. What are you smoking?

Name: Anonymous 2015-02-28 11:37

>>82
Exactly. Even Haskell's gay-ass numeric classes are better than having to use different functions for floats and integers.

Name: Anonymous 2015-02-28 11:41

>>87
OCaml allows SML-style overloading, even though explicitness is always better in terms of obvious correctness.

Name: Anonymous 2015-02-28 11:45

>>88
Haskell allows redefining the Prelude, so what? The language's defaults matter.

explicitness is always better in terms of obvious correctness
So each type should always have its own distinct functions for everything and 8.0 + 4.0 is less correct than 8 + 4? Laughable, get back to your ungeneric C toilet-scrubbing.

Name: Anonymous 2015-02-28 11:53

>>86
Your mom's weed, 'cause we're tight like that. Perl 6 is lazy by default, son.

Name: Anonymous 2015-02-28 11:59

>>89
language's defaults matter
For the purposes of your current argument only.
8.0 + 4.0 is less correct than 8 + 4?
No, 8. /. 3. is different to 8 / 3. Floats and integers are intrinsically different.

Name: Anonymous 2015-02-28 13:14

>>91
No, for lots of people. Just consider the recent heated FTP discussion.

Just because they're intrinsically different doesn't mean they should be different for the programmer. Google "generics".

Name: Anonymous 2015-02-28 13:30

>>92
I didn't think people were actually taking it seriously.
If you think that the defaults should matter so much, I would expect that you are outraged every time you have to use a compiler flag, or one of those stupid GHC directive comments that I see clogging up the top of many a haskell file. (SML-style overloading is achievable with a library and a compiler flag, by the way.)

I understand that OCaml does not have generics. However, "being different for the programmer" is my original point: obvious program correctness via explicitness. It may be more convenient for the programmer to write integer and float division the same way, but when it comes to reading it you'd potentially have a lot of context to absorb in order to understand what is actually going on.

Name: Anonymous 2015-02-28 14:12

>>93
Are SML functors achievable with a library and a compiler flag?

Yes, seeing things like a + b makes it really hard to understand what is actually going on. Is it... could it possibly be... addition?.. I once spent two and a half hours figuring out what + meant in a particular hard-to-absorb context, so I definitely hear your pain there.

We also need separate functions lengthList, lengthText, lengthArray, lengthMutableArray, sizeSet, sizeHashMap, sizeStack, sizeQueue etc just like in Scheme. That way we can be sure everything's correct by design!

Name: Anonymous 2015-02-28 14:34

>>92
It's a tradeoff. It's not because they want you to type the arithmetic operators, it's because they need you to do it for inference. It's going to come down to a preference. You can assert one or the other all day, but it's only a question of taste.

>>93
I understand that OCaml does not have generics.
No. OCaml makes the curious choice of disallowing implicit type conversions and not having any operators overloaded by type, even between scalar numeric types.

The only good thing about having different operators for float and integer operations is the explicit information. But it's not better information than you get with Haskell, where function signatures are the norm. Since global inference and elided signatures are the norm in OCaml, these different operators are necessary to match the information available. OCaml also needs them to type functions because this really is the minimum information level for OCaml's type system.

Name: Anonymous 2015-02-28 15:55

>>94
Yes, seeing things like a + b makes it really hard to understand what is actually going on. Is it... could it possibly be... addition?
It depends. If it's Javascript it's more likely to coerce one or both arguments to string and perform concatenation than it is to perform arithmetic. (If it's C++ god only knows what it's going to do.)

But Javascript is a stupid language, I can't base an argument off that. So, what if we relaxed OCaml's rule in a new language and let it dispatch on type? We have such a language, it's called F#:

> 1 + 2;;
val it : int = 3 // duh

> 1. + 2.;;
val it : float = 3.0 // cool

> "a" + "b";;
val it : string = "ab" // hang on a sec

> let f a b = a + b;;
val f : a:int -> b:int -> int // hey wait I thought + was generic? at least you can't call this on strings.

> 1. + 2;;
1. + 2;;
-----^
.../stdin(14,6): error FS0001: The type 'int' does not match the type 'float' // aw dang


OCaml and F# both treat integer and floating point arithmetic as distinct, as they should, since the underlying machine types behave very differently and these languages aim to address the underlying machine types. But Haskell cares about the distinction too, it just doesn't mind coercing between the types because the machine behaviour is abstracted away:

Prelude> import Data.Bits
Prelude Data.Bits> shiftL 33 4
528
Prelude Data.Bits> shiftL 33.3 4

<interactive>:5:1:
No instance for (Bits a0) arising from a use of `shiftL'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Bits Int -- Defined in `Data.Bits'
instance Bits Integer -- Defined in `Data.Bits'
instance Bits GHC.Types.Word -- Defined in `Data.Bits'
In the expression: shiftL 33.3 4
In an equation for `it': it = shiftL 33.3 4

<interactive>:5:8:
No instance for (Fractional a0) arising from the literal `33.3'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Fractional Double -- Defined in `GHC.Float'
instance Fractional Float -- Defined in `GHC.Float'
instance Integral a => Fractional (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
In the first argument of `shiftL', namely `33.3'
In the expression: shiftL 33.3 4
In an equation for `it': it = shiftL 33.3 4


Sort of.

Name: Anonymous 2015-02-28 16:15

>>94
Your google-fu is spectacular yet transparent. Functors are part of the language.
OK cretin, let's do it your way. Let's totally ignore the case I've been running with (division) in favour of your straw man. Let's take length. So I have a block of code containing length foo. By your assumption I don't care bout the actual type of foo, but now I want to add something to it. Oh shit! Suddenly I need to know if it's a list so I can prepend to it, or a hash so I need a key to go with the value, or a mutable array so I should be smashing my eyes open with a hammer, or maybe I can just use + on it and hope for the best, eh?

>>95
It's hardly curious. You basically answered yourself. That, and the fact that integers are treated specially by the GC though floats are boxed, but I assumed this other guy knew that because it's so common in functional languages (a trait shared with Lisp and any other language with 31- or 63-bit numbers).

Name: Anonymous 2015-02-28 16:18

>>96
Fair point, but F# can do that because it's OCaml with its guts ripped out and replaced with .NET.

Name: Anonymous 2015-02-28 16:54

>>97
It's hardly curious.
It's curious to the uninitiated and rare, so generally curious. Do you think I was trying to say it was somehow bad or wrong?

Let's take length.
I don't know what point >>94 was really trying to make here. Your bleating is really strange in the face of ( > ) which is typed 'a -> 'a -> bool. But do let us take length:

# let len x = x#length;;
val len : < length : 'a; .. > -> 'a = <fun>


Hurrah structural subtyping. (It works with nominal subtyping systems too, but you don't want that with global inference.)

We can have it both ways in OCaml but one way is clearly preferred. There is no controversy. What's there to argue about?

>>98
Thanks for explaining my post to me but check 'em.

Name: Anonymous 2015-02-28 17:32

>>99
Error: This expression has type 'a list but an expression was expected of type < length : 'a; .. >
Also (>) is
- widely known and lamented as one of a family of builtin functions that require a hole in the type system in order to work;
- inapplicable to two values of differing types.

Name: Anonymous 2015-02-28 17:46

>>97
My what? Google-fu? This coming from a person who thinks that SML functors are part of the Haskell Language? Truly retarded, I should stop reading your post now. But I'll read one more piece.

By your assumption I don't care bout the actual type of foo

No, by my assumption you don't need to call a function whose name depends on that type. Whether or not you need to care about its type depends on the concrete algorithm. For example, Oleg Kiselyov has a beautiful piece on generic zippers where he does not give a single flying fuck about the type of the thing he's zipping on - he only needs to have its traversal function. But yeah, if you want to prepend stuff to foo, you probably need to know its type - but you shouldn't have to use some shitty ungeneric function just to find the damn length of it. The programmer has been spared a bit of free time and a modicum of frustration, thank God!

I'm tired of your stupidity now and will not read any further.

Name: Anonymous 2015-02-28 17:53

>>100
Type system holes are a problem in theory and nowhere else. They're a purely academic concern. In the real world you can trust sensible programmers only to use them in idiomatic ways appropriate to what you're working on. Therefore they're an overall win for expressive power, and a litmus test for distinguishing between useful languages and academic languages.

Name: Anonymous 2015-02-28 17:55

>>102
In the real world you can trust sensible programmers

In the real world, most programmers are not sensible.

Name: Anonymous 2015-02-28 17:56

>>101
a person who thinks that SML functors are part of the Haskell Language
No. I was talking about The OCaml Language. Apparently I should have been more explicit. No wonder you are so stressed. My apologies. Google-fu was in reference to the observation that your knowledge on SML functors appeared to derive from a 5-minute google session on the search term "SML overloading".

generic zippers
Am I missing something? Why does a zipper need to be generic, and not just parameterised?

I'm saging because we're clearlyboth getting tired of this.

Name: Anonymous 2015-02-28 17:58

>>102
Considering the theory is the basis of the implementation, it's quite a practical concern.

Name: Anonymous 2015-02-28 18:01

>>100
Nice derailing.

* that error has nothing to do with the issue
* ( > ) is well-typed, but thanks for playing
* and of course: if x > y then x +. y … illustrates the same non-issue complained of in >>97

Name: Anonymous 2015-02-28 18:04

>>106
* The error is the fact that if I want your ``len'' I need everything to be an object. Tastes foul.
* > is well-typed, yes, but your interpretation of the issue is incorrect. The implementation of > is the problem here.

Name: Anonymous 2015-02-28 18:26

>>107
I need everything to be an object. Tastes foul.
This isn't an error, but: no shit, that's why we don't do it. Which is exactly what I've been saying.

The implementation of > is the problem here
That's not a hole in the type system it's just an oracular function, and no worse than read_line. OCaml is full of this stuff... I/O, Gc, FFI. You want holes in the type system? Start looking into Obj.magic, ( > ) and friends aren't going to do it for you.

Name: Anonymous 2015-02-28 20:11

>>108
It's holes all the way down.

Name: Anonymous 2015-02-28 20:20

Name: Anonymous 2015-02-28 22:21

>>109
It's holes when you hit Obj.magic or use FFI. That really doesn't have anything to do with any "holes" you might imagine in comparisons or oracles.

>>110
Still no holes. Yaron Minsky is worried about its performance, and confusion stemming from failing to understand comparisons. That seems unlikely because we're all used to writing Module.operation foo in OCaml. We would more likely mistake the operands for basic types than anything else.

But he thinks it's a good idea to include a hack based on comparison behaviour regarding objects in the standard library, tipping his hand that performance is his main concern (Jane Street is HFT or whatever.)

Name: Anonymous 2015-03-01 0:35

>>111
Really, really bad trips.

Name: Anonymous 2015-03-01 0:39

>>112
u mad cuz im rite

Name: Anonymous 2015-03-01 7:45

>>110
let () = ...
WTF this is retarded.

Name: Anonymous 2015-03-01 13:07

>>114
$ tail myprogram.ml
let () = main ();;

Name: Anonymous 2015-03-01 13:09

>>115
;D;;

Name: Anonymous 2015-03-01 15:31

>>115
Anyone care to explain to me what the fuck is going on with the spoiler span there? FF renders it inside the samp block.

Name: OCaml Language Sucks 2015-03-01 20:47

Name: Anonymous 2015-03-02 1:43

>>2
What do you use instead?

Name: Anonymous 2015-03-02 4:50

Some dickwad added overloading to OCaml with a compiler mod that works with the official binary for 4.0.2:

https://bitbucket.org/camlspotter/compiler-libs-hack

Of course it breaks inference and aborts compilation if there is not enough type information.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List