companion_cube changed the topic of #ocaml to: Discussion about the OCaml programming language | http://www.ocaml.org | OCaml 5.2.0 released: https://ocaml.org/releases/5.2.0 | Try OCaml in your browser: https://try.ocamlpro.com | Public channel logs at https://libera.irclog.whitequark.org/ocaml/
infinity0 has quit [Ping timeout: 272 seconds]
infinity0 has joined #ocaml
<discocaml> <yawaramin> hey am i missing something or is the precedence of the `?` character not documented in the OCaml operators API doc page? https://ocaml.org/manual/5.3/api/Ocaml_operators.html
<discocaml> <Kali> it has higher precedence than function application and is a prefix operator character so i'm guessing it's in the same category as ! and ~
<discocaml> <yawaramin> but my question is, it is missing from that page, right?
<discocaml> <contificate> what context does `?` appear? isn't it only optional labelled arguments
<discocaml> <contificate> which is not part of the expression language, and therefore probably not relevant to that page
<discocaml> <yawaramin> `let ( <? ) = ( * )`, `let ( <* ) = ( + )`
<discocaml> <contificate> so it's captured by the rule for `<..` no?
<discocaml> <yawaramin> how so? i don't understand
<discocaml> <contificate> the tokens are designed such that their precedence is determined by their first character
<discocaml> <contificate> so anything after is kind of irrelevant
<discocaml> <yawaramin> but what if the first char is the same for both
<discocaml> <yawaramin> so you're saying they're the same precedence?
<discocaml> <contificate> well the line for `<` in the table you linked
<discocaml> <contificate> corresponds exactly to https://github.com/ocaml/ocaml/blob/trunk/parsing/lexer.mll#L709-L710
<discocaml> <contificate> the symbol chars after aren't relevant to the precedence https://github.com/ocaml/ocaml/blob/trunk/parsing/lexer.mll#L467-L468 as far as I am aware
<discocaml> <contificate> notice the levels in the names of the tokens, `INFIXOP0`, .., `INFIXOP4`
<discocaml> <contificate> so, in some sense, the table is documenting valid first characters for infix operators with symbols after them, since the first chars determine the precedence
<discocaml> <yawaramin> ok, so `<?` and `<*` are the same precedence
<discocaml> <contificate> yes
<discocaml> <yawaramin> thanks!
<discocaml> <polyml> interesting, in ocaml you can't do `let ? = 2` or `let ( ? ) = 2` but you can do `let ( ?? ) = 2`
<discocaml> <contificate> cursed
<discocaml> <contificate> in hindsight, maybe `?` is lacking from that table
<discocaml> <polyml> in sml you can do `val ? = 2` or `datatype foo = ? of int`
<discocaml> <contificate> you can seemingly do that because of this rule:
<discocaml> <contificate> ```
<discocaml> <contificate> | ['~' '?'] symbolchar_or_hash + as op
<discocaml> <contificate> { PREFIXOP op }
<discocaml> <contificate> ```
<discocaml> <contificate> the other prefix ops are listed there
<discocaml> <contificate> low key bonkers that you can do `let (~?+~~~+=&&&&&+**) = (+);;`
<discocaml> <contificate> with great power comes great responsibility
<discocaml> <yawaramin> `let ( #!@$#!@$ ) = ...`
<discocaml> <yawaramin> some would say it's a curse
<discocaml> <polyml> `let add (*=*) (~=~) = (*=*) + (~=~);;` oh yeah I'm ocamling
<discocaml> <contificate> code reviewers HATE him! learn his one simple trick
<discocaml> <Kali> you can make prefix operators with ? and at least one other operator after it
<discocaml> <yawaramin> i call it the 'surprise!' operator
<discocaml> <Kali> which is what i was talking about when i said it had higher precedence than function application
<discocaml> <cod1r> what's the max line length of the function that you guys write
<discocaml> <cod1r> ngl i got some function in ocaml rn that are like 100 lines
<discocaml> <cod1r> ugly af
<discocaml> <yawaramin> -1 lines
<discocaml> <cod1r> huh
<discocaml> <Kali> yeah, it's missing from the docs, idk why
<discocaml> <contificate> sometimes you're kind of forced to this
<discocaml> <contificate> if you have sufficiently many cases of an ADT, even if you factor things out into their own functions, you may be bound by mutual recursion to have it as an `and` which isn't stylistically much different from having a large function (imo)
Haudegen has quit [Quit: Bin weg.]
Frostillicus has joined #ocaml
<discocaml> <dubious245> Silly question about syntax. So `:` means has-type in ocaml(1996), A quick google search reveals the original ML(1973) used `:` to mean has-type. However Haskell(1990) uses as `::` to mean has-type. Is there a reason they deviated?
Frostillicus has quit [Ping timeout: 252 seconds]
<discocaml> <barconstruction> Because they wanted to use that symbol for list cons
Frostillicus has joined #ocaml
<discocaml> <contificate> Yeah, but specifically because they expected to be writing cons more
bartholin has joined #ocaml
Guest19 has joined #ocaml
Guest19 has quit [Quit: Client closed]
Frostillicus has quit [Ping timeout: 265 seconds]
Tuplanolla has joined #ocaml
itszor has joined #ocaml
zor has quit [Ping timeout: 244 seconds]
Frostillicus has joined #ocaml
Frostillicus has quit [Ping timeout: 265 seconds]
YuGiOhJCJ has joined #ocaml
Haudegen has joined #ocaml
<discocaml> <froyo> Kali: my favorite operator for options is `or` lol
<discocaml> <froyo> `let (or) o1 o2 = Option.(fold ~some ~none:o2)`
<discocaml> <froyo> oops there's o1 at the end
<discocaml> <froyo> PolyML: you are NOT ocamling. that `(*=*)` is a comment
YuGiOhJCJ has quit [Quit: YuGiOhJCJ]
<discocaml> <._null._> ^ for the missing entry for ?. Tldr: use the page for generalities, not the one for operator precendence
<discocaml> <Kali> oh, that's fun
<discocaml> <Kali> wait, where is `>]` used? i know there's `[< ... ]` and `[> ... ]` for polyvariants but where would `>]` show up
<discocaml> <froyo> I think it was used for streams
<companion_cube> It's there for polymorphic variants
<companion_cube> Oh. The right one. I'm not sure either.
<discocaml> <froyo> I'm almost sure I've seen it in old ocaml code that matched on streams
<discocaml> <yawaramin> `[< foo; bar >]` i think
Haudegen has quit [Quit: No Ping reply in 180 seconds.]
Haudegen has joined #ocaml
Frostillicus has joined #ocaml
Haudegen has quit [Quit: Bin weg.]
ygrek has joined #ocaml
<discocaml> <polyml> rip, I would have to use `(+=+)` or make it a wider face `( *=* )`
myrkraverk has quit [Ping timeout: 252 seconds]
myrkraverk has joined #ocaml
<discocaml> <lukstafi> Has anyone successfully migrated out of Format? I might just be suffering one bug too many right now. I like imperative programming but sometimes the pain is too high.
<companion_cube> I use printer combinators for some things but Format is still a good default imho
<companion_cube> (look at containers.pp to see what I do in the specific occasions I need more control)
<discocaml> <lukstafi> I want imperative printer combinators that use precisely the syntax of Format, so they would be a drop-in replacement.
<discocaml> <lukstafi> And with a transparent document tree state that I can print using e.g. PrintBox for debugging.
<discocaml> <lukstafi> Maybe I just got myself a side project if such doesn't yet exist.
<discocaml> <lecondorduplateau> maybe Pprint can do the job https://cambium.inria.fr/~fpottier/pprint/doc/pprint/
<companion_cube> Oh yeah! You can write your own Format.formatter that uses a stack to build a document tree, I think
<companion_cube> And use your existing Format code
<discocaml> <lukstafi> Hmm there is `Containers_pp.textf`
<discocaml> <lukstafi> Ah no, that's just for outputting literal strings via Format.
<companion_cube> Look at Format itself, you can define your own formatter from a record of functions
<companion_cube> Although yeah you get strings and newlines, not boxes, but anyway
<discocaml> <lukstafi> Right, no, that's not satisfactory.
<discocaml> <Kali> ah, that makes sense
<companion_cube> Then it's indeed going to be trickier. The GADT powering format is public, I think, so you could in theory interpret it yourself to make a document tree. But it's more work and you need to change the code.
<discocaml> <Kali> yeah, it lives in CamlinternalFormatBasics i think
Frostillicus has quit [Ping timeout: 245 seconds]
Frostillicus has joined #ocaml
<discocaml> <yawaramin> what do you mean by 'migrated out of Format'? eg you want to pretty-print text? i find the `fmt` library helpful because it's combinator-based
Frostillicus has quit [Ping timeout: 252 seconds]
bibi_ has joined #ocaml
<discocaml> <lukstafi> I mean refactor a larger piece of code away from using Format (to either combinators or a solution that maintains a partial document as e.g. a zipper).
Frostillicus has joined #ocaml
<discocaml> <lukstafi> I'll compare containers_pp
<discocaml> <lukstafi> and fmt
Frostillicus has quit [Ping timeout: 252 seconds]
Frostillicus has joined #ocaml
<discocaml> <lukstafi> I'll go with containers_pp because fmt is just a continuation-based wrapper for Format, it doesn't expose a transparent state / inspectable values.
<companion_cube> containers.pp is really a simple version of pprint that ships with containers
<discocaml> <lukstafi> Alright I'll use pprint 🙂 (not depending on containers yet)
Frostillicus has quit [Ping timeout: 248 seconds]
Frostillicus has joined #ocaml
Frostillicus has quit [Ping timeout: 265 seconds]
<discocaml> <creepertv_1> :ocaml:
<discocaml> <creepertv_1> ocaml is surprisingly awesome, it's the first functional programming language i'm learning and it's way better than i imagined it'd be
<discocaml> <creepertv_1> making things and then testing them in a sandbox is certainly something else
<discocaml> <creepertv_1> let ( + ) a b = a - b;;
<discocaml> <creepertv_1> let ( - ) a b = a + b;;
<discocaml> <creepertv_1> :triggered_ocaml:
<discocaml> <creepertv_1> making things and then testing them in a sandbox is certainly very interesting
<discocaml> <creepertv_1> making things and then testing them in an interactive sandbox is certainly very interesting
<discocaml> <yawaramin> `let ( + ), ( - ) = ( - ), ( + )`
<discocaml> <froyo> 🔪
<discocaml> <froyo> have you considered not
<wbooze> lol
chrisz has quit [Quit: leaving]
ygrek has quit [Remote host closed the connection]
<discocaml> <yawaramin> `type bool = ()`
<discocaml> <._null._> `type bool = true | false`
<discocaml> <yawaramin> lol. diabolical
<discocaml> <Kali> `type bool = [] | (::)`
<discocaml> <Kali> `type 'a list = false | true of 'a * 'a list`
Frostillicus has joined #ocaml
Frostillicus has quit [Ping timeout: 265 seconds]
<discocaml> <rezwanarefin01> This reminds me of how in Python you can change the meaning of small number literals, eg. the literal `2` to refer to the number `3` etc.
<discocaml> <creepertv_1> wait really
<discocaml> <creepertv_1> how
YuGiOhJCJ has joined #ocaml
Serpent7776 has joined #ocaml
Serpent7776 has quit [Ping timeout: 252 seconds]
<discocaml> <creepertv_1> lol this websites hilarious
<discocaml> <creepertv_1> didn't know about that c++ feature
bartholin has quit [Remote host closed the connection]
<discocaml> <edhebi> good ol c preprocessor
<discocaml> <deepspacejohn> At least in OCaml all of your bad decisions are scoped to the current module
wbooze_ has joined #ocaml
wbooze has quit [Ping timeout: 252 seconds]
wbooze_ is now known as wbooze
Mister_Magister has quit [Quit: bye]
Mister_Magister has joined #ocaml