williewi` has quit [Quit: ERC 5.4 (IRC client for GNU Emacs 28.2)]
Guest7877 has joined #ocaml
bobo_ has joined #ocaml
spip has quit [Ping timeout: 265 seconds]
Guest7877 has left #ocaml [#ocaml]
Tuplanolla has joined #ocaml
aldos has joined #ocaml
<aldos>
hi, i was reading the tutorial, i have question on type inferece output
<aldos>
let deriv f dx = function x -> (f (x +. dx) -. f x) /. dx;;
<aldos>
system output of this phrase is - val deriv : (float -> float) -> float -> float -> float = <fun>
<aldos>
I see there is a pair of () in the beginning, meaning taking a funciton?
<aldos>
but it returns a function, which takes one float and returns a float, but i don't see any () around the last two floats
Serpent7776 has joined #ocaml
<aldos>
i am seeing same kind thing other places too
<ski>
aldos : the `->' infix operator is right-associative, meaning that `foo -> bar -> baz' is parsed as `foo -> (bar -> baz)'. compare with e.g. `/.' being left-associative, meaning that `x /. y /. z' is parsed as `(x /. y) /. z'
<ski>
so, fully bracketted, the signature would look like
<ski>
similarly, the function application "invisible juxtaposition operator" is also left-associative, meaning that `deriv f dx x' parses as `((deriv f) dx) x'
olle has joined #ocaml
<ski>
assuming that you have some variables `f',`dx',`x' in scope such that
<aldos>
hmm, i think i understand. i quite new two functional progamming, first time learning
<aldos>
\me just made a lot of typos.....
* aldos
made typo saying i made a lot of typos
<ski>
note that you could also have defined `deriv' as :
<ski>
let deriv f dx x = (f (x +. dx) -. f x) /. dx;;
<ski>
or
<ski>
let deriv f = function dx -> function x -> (f (x +. dx) -. f x) /. dx;;
<ski>
or
<ski>
let deriv = function f -> function dx -> function x -> (f (x +. dx) -. f x) /. dx;;
<ski>
or
<ski>
let deriv = fun f dx x -> (f (x +. dx) -. f x) /. dx;;
<ski>
presumably they chose the one would showed above, to emphasize that we think of `deriv' as computing a new *function*, given an input function `f', and a small offset `dx'
<ski>
s/one would showed/one you showed/
<ski>
aldos : have you heard about currying, and partial application ?
<aldos>
i heard about currying
<ski>
well, both are about "multiple parameter functions"
<ski>
OCaml doesn't have those. all functions in OCaml takes exactly one input parameter/argument
<aldos>
opps, i thought the are about single parameter functions
<ski>
however, you can *encode*/*represent* multiple parameter functions, in OCaml .. in fact, you can do it in *two* main (different) ways
<ski>
one can be called "tupling". in this way, you pack all the would-be multiple parameters into a single compound aggregate, making that the actual single parameter of your function
<aldos>
like one would define add as a function which takes one param and returns a function which takes one param and return a value
<ski>
typically, you'd pack them into a tuple .. but one could also pack them into a record (`struct', or even "object", if you prefer), or possibly sometimes some other compound structure, like a list, vector or array, or perhaps finite map of some sort (in math, bag/multiset, and set, isn't too uncommon, either)
<ski>
so, you could have said
<aldos>
hmm, i need some more reading before
<ski>
let derivTupled f_and_dx = function x -> ((fst f_and_dx) (x +. snd f_and_dx) -. (fst f_and_dx) x) /. snd f_and_dx;;
<ski>
where `fst' and `snd' extracts the actual `f' and `dx' components of the `f_and_dx' pair that we're interested in (we could have used a `let' in the body of the function, to extract these once, rather than two times for each)
<ski>
however, because OCaml has *pattern-matching* (in this case on tuples), we could write this instead simply as
aldos has quit [Remote host closed the connection]
<ski>
let derivTupled (f,dx) = function x -> (f (x +. dx) -. f x) /. dx;;
<ski>
(generally you want to use pattern-matching, when you can, rather than accessor/selector functions like `fst',`snd', since it becomes much more readable)
<ski>
now, the *other* way to encode multiple parameter functions is, as you hopefully have already seen to some extent, to make a function that accepts one parameter, and returns/computes a new function that accepts all the remaining ones (usually, one at at time, returning new functions, until we've taken all parameters and can return the final result)
<ski>
this is the `deriv' version you showed above
adanwan has quit [Remote host closed the connection]
adanwan has joined #ocaml
<ski>
"Or is there a way to pick only 'a, and ignore 'b and possibly 'c, etc" -- hm, i guess you want some way to have the components referred to by name/label, rather than position, and then being able to only mention the ones which are relevant at a particular point
<ski>
(this reminds me of attribute grammars .. hm, and perhaps it would be possible to do something with row types and row polymorphism ?)
<ski>
hm .. (after looking up `let*' in the manual ..) i think you'd need to store both the input and the output (type) state as parameters of your type `t' ? .. meaning indexed monads, rather than plain monads
<ski>
(hm, vaguely reminds me of McBride doing something with expressing Hoare triples in, i think, a somewhat different way (predicate transformers ?) .. now, if i could recall in which paper i saw that ..)
<olle>
haha lots of parenthesis here
<olle>
ski: yeah, type-level records and then match on them. Maybe a weird feature to want, dunno
<ski>
not really .. i've wanted it, several times, in Haskell (e.g. indirecting fixed-points of mutually-recursive ASTs)
<ski>
there is one GADT trick one can use, to simulate type records, assuming all components have the same kind
<olle>
Yeah?
<ski>
basically, representing k * k as bool -> k .. hm, although now i'm wondering if OCaml supports datakinds (and higher-order types) yet (here bool would be a datakind) .. anyway, the idea is that, in a GADT, instead of matching on a type record (naming the components) in the result type of your data constructors, you call the "record" say 'f and then you pass your "record tags/labels" as argument to
<ski>
that, when you want to refer to a particular component, like false 'f
sagax has joined #ocaml
<ski>
(anyway, you only wanting the mention the relevant components does sound a bit like the "expression problem", and how semantic actions (specifying how to compute synthesized attributed from inherited ones, possibly also involving state-threaded ones) attaches to productions in an attribute grammar only need to mention the relevant attributes for that semantic action .. you can define things separately, and
energizer has quit [Quit: ZNC 1.7.0+deb0+xenial1 - https://znc.in]
habnabit_ has joined #ocaml
oisota has joined #ocaml
energizer has joined #ocaml
<olle>
Bit too complicated for me, I'm afraid
olle has quit [Ping timeout: 252 seconds]
perrierjouet has joined #ocaml
* jedb
finds the @@ and |> operator definitions and scratches his head
<jedb>
let ( @@ ) f g x = f (g x)
<jedb>
let ( |> ) f x = f x
<jedb>
there we go, much better :)
perrierjouet has quit [Remote host closed the connection]
perrierjouet has joined #ocaml
adanwan has quit [Remote host closed the connection]
jao has joined #ocaml
adanwan has joined #ocaml
* ski
notes that jedb flipped the `|>'
<jedb>
it makes more sense that way
<ski>
hm, i thought there already was a function composition operator ..
<jedb>
apparently not, which was the first problem
<jedb>
so if one of @@ and |> is going to be composition, then it should be the higher priority one that coincidentally looks like the mathematical composition operator, making @@ composition and leaving |> to be application
<ski>
makes sense
* ski
's currently wondering whether `let*' works with Lwt
perrierjouet has quit [Quit: WeeChat 3.6]
wingsorc__ has joined #ocaml
perrierjouet has joined #ocaml
azimut has quit [Ping timeout: 258 seconds]
bartholin has quit [Remote host closed the connection]
olle has joined #ocaml
bartholin has joined #ocaml
<reynir>
ski: yea, you can open Lwt.Syntax for let* etc