<discocaml>
<Kali> indeed; if you want a lower-level functional language, perhaps take a look at something like Roc
<discocaml>
<Kali> or Ante
<discocaml>
<leviroth> Guess it depends on what you mean by lower-level. It doesn’t give you very fine-grained control over memory layout and it’s garbage collected, so it’s not going to do well in some domains where you’d traditionally use C etc.
<discocaml>
<tesaear> Interacting and modifying user input
<discocaml>
<tesaear> Interacting with and modifying user input
<discocaml>
<tesaear> "We want Roc to run faster than any non-systems language (like C, C++, Rust, or Zig) "
<discocaml>
<tesaear> Wat?
<discocaml>
<Kali> that sentence is a little confusingly worded, they mean "We want Roc to run faster than any non-systems language (systems languages being things like C, C++, Rust, or Zig)"
<discocaml>
<tesaear> Ahhhhh
<discocaml>
<tesaear> Yes
<discocaml>
<leviroth> I’m confused, interacting with user input is a really common task for programs and I wouldn’t have thought that it’s a particularly low-level concern
<discocaml>
<tesaear> I thought it was
<discocaml>
<tesaear> If we're manipulating how the mouse moves for example
<discocaml>
<darrenldl> but i don't think it's for general FP
<discocaml>
<darrenldl> some other flavours of SML might be faster, but overall ocaml is up there afaik
technomancy[m] has left #ocaml [#ocaml]
bgs has joined #ocaml
bartholin has joined #ocaml
bartholin has quit [Quit: Leaving]
bgs has quit [Remote host closed the connection]
pieguy128_ has quit [*.net *.split]
ocabot has quit [*.net *.split]
ansiwen has quit [*.net *.split]
mal`` has quit [*.net *.split]
micro has quit [*.net *.split]
theblatte has quit [*.net *.split]
fds_ has quit [*.net *.split]
dinosaure2 has quit [*.net *.split]
oisota has quit [*.net *.split]
nore has quit [*.net *.split]
theblatte has joined #ocaml
fds has joined #ocaml
micro has joined #ocaml
oisota has joined #ocaml
micro has quit [Changing host]
micro has joined #ocaml
ansiwen_ has joined #ocaml
nore has joined #ocaml
mal`` has joined #ocaml
pieguy128 has joined #ocaml
dinosaure2 has joined #ocaml
ocabot has joined #ocaml
neiluj has joined #ocaml
<discocaml>
<deadinside> hey everybody could anybody help me with this please? 😭 i’m completely new to ocaml and i’ve been stuck on this single line of code for over a week and i’m on the verge of giving up on ocaml
<discocaml>
<deadinside>
<discocaml>
<deadinside> i’ve tried to figure it out on my own but all explanations i could find online are all too hard for me to understand. how do i get this code to run 1. in utop, 2. using ocamlopt, and 3. using dune? i want to know all 3 ways to run it. is there something i have to import or `#require` that i’ve missed?
<discocaml>
<deadinside>
<discocaml>
<deadinside> would really appreciate any help!!
<discocaml>
<NULL> `[%` is ppx syntax, do you need it ? I wouldn't consider ppxes very beginner-safe
<discocaml>
<deadinside> the book i’m reading brought it up so i wanna have at least a basic understanding of it
azimut_ has quit [Ping timeout: 255 seconds]
<discocaml>
<darrenldl> what's the book?
<discocaml>
<darrenldl> you'll need to load the ppx into utop in some shape or form first
<discocaml>
<darrenldl> for `get_env` though, i'd just use the function directly
<discocaml>
<darrenldl> `Sys.getenv` or whatever it's called
<discocaml>
<deadinside> yeah i know there’s a way to do it without a ppx, but how do i do it with `[%get_env "..."]`? and the book is real world ocaml
<discocaml>
<deadinside> what flag/etc do i use to load the ppx into utop? also how do i compile that same code with ocamlopt and dune?
spip has joined #ocaml
<discocaml>
<darrenldl> which chapter is it?
<discocaml>
<deadinside> chater 6, why?
<discocaml>
<darrenldl> seems weird it doesnt give instruction on setting it up
<discocaml>
<deadinside> yeah well could you please point to any resources or tell me how to load the ppx into utop and how to compile the code above using ocamlopt & dune?
<discocaml>
<deadinside> Error: Reference to undefined global `Location'```
<discocaml>
<deadinside> well would it be possible to download it & compile it myself and run it?
<discocaml>
<deadinside> and how would i do go about doing that?
<discocaml>
<Armael> yea ppxlib is a lib for building ppxes, probably not what you want
<discocaml>
<Armael> (AFAIK)
<discocaml>
<Armael> what were you trying to do originally?
<discocaml>
<deadinside> this isn’t part of any project or anything, i’m new to ocaml as i’ve mentioned, trying my hand at various things and just wanted to try out some preprocessors
<discocaml>
<deadinside> if i were to download the repo the article links to and compile it myself to get the code in my original question to run, how could i do that?
<discocaml>
<Armael> ah, maybe a better preprocessor to try out is ppx_deriving, which allows you to derive e.g. printing functions for type declarations
<discocaml>
<deadinside> yeah i’ve seen an example of that in the book i’m currently reading
<discocaml>
<Armael> so you can do `type t = A | B [@@deriving show]` and get a `t -> string` function
<discocaml>
<deadinside> but what about that one? 🤔
<discocaml>
<Armael> no idea 😄
<discocaml>
<deadinside> ah welp appreciate your help nonetheless!
<discocaml>
<deadinside> has anybody compiled and run their own preprocessor? can anybody help me compile that preprocessor and try it out please!
<discocaml>
<Minicorgi> I don't see any `get_env` in chapter 6. Which edition of the book are you using?
AnotherGuest67 has joined #ocaml
wingsorc has quit [Ping timeout: 248 seconds]
<discocaml>
<dumbpotato> that particular line of code is from https://ocaml.org/docs/metaprogramming like i’ve already said, the book uses `[@@deriving fields]` and this is the first time preprocessors are brought up and they aren’t explained in much detail so i was looking into them on my own and wanted to try out some more preprocessors. anyway, how can i compile that preprocessor myself and run it?
<discocaml>
<dumbpotato> do i still have to have a copy of the directory even though i’ve already installed ppxlib on my machine with `opam install ppxlib`?
<discocaml>
<dumbpotato> 1. do i still have to have a copy of the directory even though i’ve already installed ppxlib on my machine with `opam install ppxlib`?
<discocaml>
<dumbpotato> 2. do i download the whole ppxlib repo or just the directory with the preprocessor?
<discocaml>
<dumbpotato>
<discocaml>
<dumbpotato> sorry, not familiar with dune yet
<discocaml>
<leviroth> Yes. `ppxlib` is just a library for building preprocessors; it doesn't contain any actual rewriters.
<discocaml>
<leviroth> Re (2), the link I gave isn't to part of the ppxlib *repo*, it's to a specific repo within the ppxlib *organization*
<discocaml>
<leviroth> Re (2), the link I gave isn't to part of the ppxlib *repo*, it's to a specific repo within the ocaml-ppx *organization*
<discocaml>
<dumbpotato> so i just need the directory with ppx_get_env.ml, ppx_get_env.mli, and their dune file, did i get that right?
<discocaml>
<leviroth> Yep, that's right
<discocaml>
<dumbpotato> really appreciate your help btw, things are finally starting to make sense after a week 🥲
<discocaml>
<dumbpotato> okay i’ll give that a try, thank you so much for your help!
<discocaml>
<leviroth> Oh sorry I was totally confused when I said I linked to a specific repository within the organization. You're right that this is just one directory within a larger repo.
<discocaml>
<leviroth> (It should still work to just have those three files in a directory, though)
<discocaml>
<leviroth> To try out the ppx in utop, it looks like it's sufficient to `cd` into the directory with that code and run `dune utop`
<discocaml>
<dumbpotato> @therewolf okay so i’ve created a directory and inside it i have:
<discocaml>
<dumbpotato> and a nested directory with the 3 preprocessor files. but i still got this error when i tried to compile it, what am i doing wrong? 😔
<discocaml>
<dumbpotato> ```$ dune build main.exe
<discocaml>
<dumbpotato> File "dune", line 3, characters 16-19:
<discocaml>
<dumbpotato> > let () = Stdio.printf "compiled on %s\n" [%get_env "OSTYPE"]```
<discocaml>
<dumbpotato>
<discocaml>
<dumbpotato> and a nested directory with the 3 preprocessor files. but i still got this error when i tried to compile it, what am i doing wrong? 😔
<discocaml>
<dumbpotato> ```$ dune build main.exe
<discocaml>
<dumbpotato> File "dune", line 3, characters 16-19:
<discocaml>
<dumbpotato> the weirdest thing happens lol omg why 🥲
<discocaml>
<leviroth> Hmm your utop is auto-opening `Base`, which I don't think matters here, but I wanted to note it in case it comes up later.
<discocaml>
<leviroth> Can your utop see any environment variables? What does `Unix.environment ()` do?
<discocaml>
<leviroth> Oh I *also* don't have OSTYPE within dune! That's weird!
<discocaml>
<leviroth> I'm starting to think OSTYPE is not actually an environment variable
<discocaml>
<dumbpotato> Unix.environment () returns a string list
<discocaml>
<dumbpotato> but i can echo it in the terminal though
<discocaml>
<leviroth> Yeah but that just means it's a shell variable
<discocaml>
<dumbpotato> oh so if i change the code to something like `[%get_env "USER"]`
<discocaml>
<dumbpotato> it will work?
<discocaml>
<leviroth> If you do `OSTYPE=darwin utop`, does `Sys.getenv "OSTYPE"` work?
<discocaml>
<leviroth> Yeah that's my hypothesis
<discocaml>
<leviroth> However there is another thing I'm worried about, which is that `OSTYPE=darwin dune build main.exe` also didn't work
<discocaml>
<dumbpotato> ```$ dune build main.exe
<discocaml>
<dumbpotato> File "main.ml", line 1, characters 0-9:
<discocaml>
<dumbpotato> 1 | open Base
<discocaml>
<dumbpotato> ^^^^^^^^^
<discocaml>
<dumbpotato> Error (warning 33 [unused-open]): unused open Base.```
<discocaml>
<dumbpotato> okay what is this now i’ve included `(libraries base stdio)` in `base` wow it’s kinda exhausting to suck this bad lol
<discocaml>
<leviroth> In that case we explicitly set OSTYPE *as an environment variable* while invoking dune, which suggests that the environment isn't being inherited by the ppx in the way I would have expected.
<discocaml>
<dumbpotato> i shouldn’t open it if i’m not gonna use it?
<discocaml>
<leviroth> I would consider writing `open! Base` if you're using base
<discocaml>
<dumbpotato> why is that a hard error though instead of just a warning lol
<discocaml>
<leviroth> because dune turns all warnings into errors
<discocaml>
<dumbpotato> compiled by [my username]```
<discocaml>
<dumbpotato> ah there we go
<discocaml>
<dumbpotato> thank you so much for your help!
<discocaml>
<leviroth> 🙏
<discocaml>
<leviroth> I think it's a documentation issue that "OSTYPE" is used in that example. It's definitely not an environment variable (normally).
<discocaml>
<dumbpotato> haha well i suppose the road to fluency in ocaml is gonna be a hell of a rocky ride 😅
<discocaml>
<dumbpotato> haha well i suppose the path to fluency in ocaml is gonna be a hell of a rocky ride 😅
<discocaml>
<Minicorgi> I'm also learning it but it has less concepts than say Haskell for example, so maybe you will be fine 🙂
dinosaure2 is now known as dinosaure
<discocaml>
<Minicorgi> Having used Clojure before, I'm not super sold on ppx
<neiluj>
because of the meta programming capabilities of lisps?
<discocaml>
<Minicorgi> Yes, much simple to extend the language
<olle>
Is there a pipe operator that deals with None?
<olle>
f |> g |> h -- if any returns None, stop and return None
<olle>
Or would that have to be let* ?
<olle>
|>* ?
oriba has joined #ocaml
<discocaml>
<deepspacejohn> There isn’t a built in function, but you can use `f |> Option.map g` (or define your own that does that)
<discocaml>
<deepspacejohn> There isn’t a built in function, but you can use `f |> Option.map g` (or define your own that does that)
<discocaml>
<deepspacejohn> let* is more designed for this scenario, but again you need to define your own. OCaml just provides the syntax, not the stdlib functions
<discocaml>
<Kali> >>= is exactly what you described
<olle>
option type != monad
<discocaml>
<Kali> ?
<discocaml>
<Kali> option is a monad; obviously not the only monad, but it is one
<discocaml>
<Kali> i am not sure what you mean
<discocaml>
<Kali> `Option.(>>=)` (or `Option.bind` in Stdlib) is precisely what you described: a function that short-circuits a chain to None if any function inside of it returns None
<discocaml>
<Kali> `>>=`, `bind`, and `let*` are all the same (or at least, they should be; there's nothing stopping you from defining them on something that isn't a monad)
<olle>
Option type is not a type
<olle>
Sorry
<olle>
Option type is not a monad. Just a normal type.
<olle>
People keep confusing that for some reason
<olle>
type 'a option = Some 'a | None
<discocaml>
<Kali> *Some of 'a
<discocaml>
<Kali> being a monad is an abstract property of a type, not a type itself
<discocaml>
<Kali> any monad `'a t` satisfies three laws given two functions `return : 'a -> 'a t` and `bind : 'a t -> ('a -> 'b t) -> 'b t`:
<olle>
Ehm
<olle>
Well in any case, I'm not looking for the Option or Maybe monad
<olle>
I was asking about a pipe operator that deals with option types automatically.
<olle>
But I guess the answer is no. :)
<discocaml>
<Kali> ```
<discocaml>
<Kali> return a >>= f is the same as f a
<discocaml>
<Kali> m >>= return is the same as m
<discocaml>
<Kali> (m >>= g) >>= h is the same as m >>= (fun x -> g x >> h)
<discocaml>
<Kali> ```
<discocaml>
<Kali> ```
<discocaml>
<Kali> return a >>= f is the same as f a
<discocaml>
<Kali> m >>= return is the same as m
<discocaml>
<Kali> (m >>= g) >>= h is the same as m >>= (fun x -> g x >> h)
<discocaml>
<Kali> ```
<companion_cube>
"a pipe operator that deals with option" sounds a lot like the option monad
<discocaml>
<Kali> you want a pipe operator that will return None for the rest of the chain if any of functions in that chain return None?
<olle>
companion_cube: I realize that. Was just curious.
<discocaml>
<Kali> that description exactly matches `>>=`
<olle>
Yeah. So?
<olle>
There can be more than one solution to a problem.
<companion_cube>
so there's your answer
<discocaml>
<Kali> try defining one yourself: you will find that the definition of `bind`, `>>=`, whatever you want to call it, is the most natural solution
Haudegen has joined #ocaml
<discocaml>
<Kali> i somewhat doubt there even is any other solution to it
<discocaml>
<Kali> `let (>>=) o f = match o with None -> None | Some x -> f x` (or `let (>>=) o f = Option.(join (map f o))`, if you allow using existing Option module functions)
<olle>
Isn't |> just f a = a f or whatever? Wouldn't it be possible to check for option there? `if None then None else f a`
<discocaml>
<Kali> that is exactly what i just typed out: `let (>>=) o f = match o with None -> None | Some x -> f x`
<discocaml>
<leviroth> There can be more than one solution to a problem but given that you’ve specified exactly the behavior of the function you want, and Option.bind is the function with that behavior, I’m not sure what you’d view as an alternative solution.
<discocaml>
<Kali> ^
<olle>
:d
<neiluj>
basically instead of checking for None in your functions the check for None is performed by the bind operator that allows chaining a computation on optional values
<neiluj>
so you get "a pipe operator that deals with option"
<olle>
Yeah ok, Kali's def makes sense
<olle>
Thanks :)
<discocaml>
<Kali> no problem
waleee has joined #ocaml
waleee has quit [Quit: WeeChat 3.8]
azimut has joined #ocaml
mbuf has quit [Quit: Leaving]
Haudegen has quit [Quit: Bin weg.]
glondu[m] has quit [Quit: You have been kicked for being idle]