infinity0 has quit [Remote host closed the connection]
derek_ has joined #ocaml
derek_ is now known as Guest37193
infinity0 has joined #ocaml
infinity0 has quit [Remote host closed the connection]
<Guest37193>
kind peeps - I just did "opam install yojson", then in utop I try "open Yojson" and get Unbound module Yojson. What am I doing wrong? [on OSX]
infinity0 has joined #ocaml
infinity0 has quit [Remote host closed the connection]
sh0t has quit [Remote host closed the connection]
infinity0 has joined #ocaml
infinity0 has quit [Remote host closed the connection]
<lyxia>
Guest37193: #require "yojson";;
<Guest37193>
thank you, @lyxia!
AlexDenisov has joined #ocaml
ziyourenxiang has joined #ocaml
FreeBird_ has joined #ocaml
Guest37193 has quit [Quit: Page closed]
FreeBirdLjj has quit [Ping timeout: 260 seconds]
n4323 has joined #ocaml
n4323 has quit [Ping timeout: 260 seconds]
copy` has quit [Quit: Connection closed for inactivity]
mfp has quit [Ping timeout: 246 seconds]
pierpa has quit [Quit: Page closed]
average has quit [Quit: leaving]
kassens has joined #ocaml
<kassens>
Is there a way to prevent function types to be inferred to precisely in the same module? For example, a helper to print an Option: ```print_or_empty : ('a -> string) -> 'a option -> string = fun f opt -> "..."```, if I call it in the same module with an `Foo option` and `Bar option`, the second call fails because it expects whatever was used first.
<lyxia>
kassens: that should work though, so something else is wrong.
<kassens>
Found that it's working now after moving it out of a `let rec ... and ... and` construct into its own let
kamog has quit [Quit: ERC (IRC client for Emacs 25.2.1)]
diphuser has joined #ocaml
infinity0 has joined #ocaml
rpg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
segmond has joined #ocaml
_whitelogger has joined #ocaml
n4323 has joined #ocaml
diphuser has quit [Ping timeout: 260 seconds]
shinnya has joined #ocaml
_whitelogger has joined #ocaml
_whitelogger has joined #ocaml
_whitelogger has joined #ocaml
FreeBird_ has quit [Remote host closed the connection]
Mercuria1Alchemi has joined #ocaml
segmond has quit [Quit: l8r]
n4323 has quit [Ping timeout: 260 seconds]
diphuser has joined #ocaml
kassens has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
olibjerd has joined #ocaml
_whitelogger has joined #ocaml
jnavila has joined #ocaml
ygrek has quit [Ping timeout: 246 seconds]
gndl has joined #ocaml
gndl has left #ocaml [#ocaml]
mfp has joined #ocaml
FreeBirdLjj has joined #ocaml
average has joined #ocaml
AlexRussia has quit [Ping timeout: 260 seconds]
whirm has joined #ocaml
tane has joined #ocaml
AlexRussia has joined #ocaml
rpip has joined #ocaml
TheLemonMan has joined #ocaml
jao has joined #ocaml
AlexDenisov has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
AlexDenisov has joined #ocaml
AlexDenisov has quit [Client Quit]
freusque has joined #ocaml
<companion_cube>
mfp: hey, didn't see you release sqlexpr 0.8, congrats!
freusque has quit [Quit: WeeChat 1.7]
fedruantine has quit [Read error: Connection reset by peer]
spion has quit [Ping timeout: 240 seconds]
spion has joined #ocaml
olibjerd has quit [Ping timeout: 255 seconds]
rpg has joined #ocaml
freusque has joined #ocaml
AlexRussia has quit [Ping timeout: 272 seconds]
freusque has quit [Quit: WeeChat 1.7]
spion has quit [Ping timeout: 260 seconds]
spion has joined #ocaml
AlexRussia has joined #ocaml
olibjerd has joined #ocaml
FreeBirdLjj has quit [Remote host closed the connection]
whirm has quit [Remote host closed the connection]
whirm has joined #ocaml
Simn has joined #ocaml
freusque has joined #ocaml
FreeBirdLjj has joined #ocaml
whirm has quit [Ping timeout: 255 seconds]
sz0 has joined #ocaml
FreeBirdLjj has quit [Remote host closed the connection]
whirm has joined #ocaml
Mercuria1Alchemi has quit [Ping timeout: 268 seconds]
freusque has quit [Ping timeout: 255 seconds]
whirm has quit [Remote host closed the connection]
henrytill_ is now known as henrytill
jao has quit [Ping timeout: 240 seconds]
henrytill has quit [Changing host]
henrytill has joined #ocaml
shinnya has quit [Ping timeout: 240 seconds]
sh0t has joined #ocaml
TheLemonMan has quit [Quit: "It's now safe to turn off your computer."]
FreeBirdLjj has joined #ocaml
FreeBirdLjj has quit [Ping timeout: 260 seconds]
Mercuria1Alchemi has joined #ocaml
AlexDenisov has joined #ocaml
ziyourenxiang has quit [Quit: Leaving]
FreeBirdLjj has joined #ocaml
Simn has quit [Ping timeout: 255 seconds]
barcabuona has joined #ocaml
<barcabuona>
hey guys if i do "type ide = string" then all strings will become ide (which is not what i want. If i do "type ide = Id of string" then i cannot do "type expr = Int of int | ide".
<barcabuona>
while in the first case i have "type expr = Int of int | Var of ide"
<barcabuona>
and the thing is i currently can choose between these 2 options
<barcabuona>
1. a user can enter Var("x") to specify a variable but i cannot have the interpreter distinguish between variable and strings
<barcabuona>
2. a user needs to type Var(Id("x")) to distinguish variable x from string "x"
<barcabuona>
does anybody have any suggestion to allow me to have the user type Var("x") and "x" to distinguish vars/strings and at the same time the interpreter can distinguish them as well?
<barcabuona>
i can at most think of "type ide = Id of string" and "type expr = Var of ide" and "let var x = Var(Id(x))"
<lyxia>
Var("x") String("x")
<lyxia>
why do both have to be under the same constructor otherwise?
<barcabuona>
lyxia: i dont follow
<lyxia>
barcabuona: have one constructor (Var) for variables, one constructor (String) for strings
<lyxia>
type expr = Int of int | String of string | Var of string
<barcabuona>
lyxia: i cannot do that. well i already have String of string. But ide is a higher level concept as it does not only appear within expr. Therefore Var of ide is required
<barcabuona>
you see i have an "type env = ide->value"
<barcabuona>
and value is the internal types for my interpreter
<barcabuona>
you may consider expr to be the external types
<lyxia>
how about hiding the definition of expr and only exposing functions instead of constructors? that would let you use whatever implementation is more convenient
<barcabuona>
lyxia: that's not such a great solution. the whole point of having types is to separate the domains, if i start patching stuff up with functions it's not a direct representation of my domains
<barcabuona>
the user would not input expr, he would input functions that map to expr
<lyxia>
If you're writing an embedded DSL you can't have "x" to be of type expr anyway.
TheLemonMan has joined #ocaml
<lyxia>
so the user has to write something like from_string "x"
<barcabuona>
yeah it's going to be Var("x")
<barcabuona>
the whole issue is that ocaml can't embed types without constructors
<barcabuona>
you see i have an identifier domain
<barcabuona>
and i have an expression (user) domain
<barcabuona>
and a values (interpreter) domain
<barcabuona>
to have some state, the interpreter domain is extended with a function that maps identifiers -> to values
<barcabuona>
so type env = ide -> value
<lyxia>
And how does my suggestion of exposing functions contradict the point of having types
<barcabuona>
and also type expr = Int of int .... Var of ide
<lyxia>
I think I just didn't understand your question at all.
<lyxia>
"the whole issue is that ocaml can't embed types without constructors" <- didn't that answer your question?
segmond has joined #ocaml
<Drup>
I don't really understand what is the problem either.
<barcabuona>
the problem is...
<barcabuona>
the interpreter must be able to differentiate strings from identifiers because well they're not the same
<barcabuona>
or maybe they are?
<barcabuona>
...considering i dont use string anywehere else. i actually have an internal type for strings ...
<Drup>
barcabuona: that's why you get two different constructors, String and Var.
<barcabuona>
Drup: that's not for the interpreter
<barcabuona>
that's for the DSL domain
<Drup>
No, it's for both.
<barcabuona>
...
<barcabuona>
type expr = Int of int | String of string
<barcabuona>
type value = EInt of int | EString of string
<barcabuona>
so they're different
<barcabuona>
but type ide = string (IF only it was possible)
<barcabuona>
the thing is ide appears in both DSL and interpreter domains
<barcabuona>
alright this is not making any sense give me a second to reconsider
<lyxia>
maybe paste the actual types you are currently working with somewhere...
<lyxia>
so what about that does not distinguish strings from identifiers
FreeBirdLjj has quit [Remote host closed the connection]
AlexRussia has quit [Ping timeout: 260 seconds]
<barcabuona>
the thing is EXPR = Id | ... | Lambda(Id,EXPR). but also ENV: Id -> VALUE. so the user must be able to type Id("x") and Lamdba(Id("x"),..) and mean the same thing. but since Id is a type that also appears within ENV i cannot have it nested inside of EXPR like Id of string. it must be its own type. That means that EXPR would have to directly embed it (no constructor) but it cant
<barcabuona>
lyxia: the fact that ide==string when i set ocaml to type ide = string
<barcabuona>
and ocaml will show me that String("x") is actually of type String of ide
<barcabuona>
instead of String of string
<barcabuona>
basically what i really really need is "type expr = ide | .... | Lambda of ide*expr
<Drup>
So, your problem is that either you have one extra constructor which you would prefer to avoid, or that you don't like how OCaml prints your type ?
<barcabuona>
Drup: i think so
<Drup>
You might be overthinking this a little bit :p
<barcabuona>
you might be right
<Drup>
Either you insist on enforcing a strong separation between types and strings (and then you add an extra constructor) or you don't (and then you use a type alias)
<Drup>
it's an implementation choice
<Drup>
ids and strings*
<Drup>
regardless of the choice, it's internal detail which you can easily hide in your API
<barcabuona>
you see i must let the user write down ides. i must also let the environment handle ides. and that is done within a match with Id(x) -> (envp x) or something
<barcabuona>
but obviously to match that it would have to become Var(Id(x)) -> (envp x)
<Drup>
is that really a problem ?
<barcabuona>
i can't have the user type Var(Id("x")) just to represent an id its ridiculous
<Drup>
let var x = Var(Id x)
<barcabuona>
* it would have to become Var(x) -> (envp x) where x= Id("...")
<Drup>
tada, problem solved :p
<barcabuona>
Drup: that was my original solution
kassens has joined #ocaml
<barcabuona>
i guess it might have to do..
<Drup>
Although, if you expose to your users that ids are like strings, and let them choose their id freely, what's the point of having a separation internally ?
AlexRussia has joined #ocaml
<barcabuona>
i just gathered the issue. this is my desired use case https://ptpb.pw/m9G7
<barcabuona>
as you can see this would require ocaml to be able to match a type and not a constructor
<barcabuona>
so i obviously must allow ocaml to match with a constructor. the only solution i can think of is:
<barcabuona>
Drup: you are right by saying that internally type ide = string and type value = ... | EString of string would mean that i never actually come across strings
<barcabuona>
but still i must be able to differentiate between the 2 when i build upon them
<barcabuona>
so if i ever want to make some operators for strings i'll have to de-encapsulate either String or EString (the internal type) and do ocaml operations on the string and then reincapsulate
<barcabuona>
but ide is not something you can do string operations on, so while i can notice this from my interpreter ocaml cannot
<barcabuona>
and i need ocaml to differentiate them. at the same time EString of string sounds so wrong
<barcabuona>
and type env = ide -> value, not string -> value. ide must be its own type
<lyxia>
let lambda x y = Lambda(Id x, y)
<lyxia>
problem solved (bis)
<Drup>
You are really overthinking this. Just pick one of the two solution, and go forward with your interpreter, and if you don't like it, change it later
<barcabuona>
lyxia: but is the syntax consistent? a user must be able to type both Id("x") and Lambda(Id("x"),...). the issue is what ocaml can match. it must match ide in both cases but it cannot in the first case because it doesn't have a constructor that contains ide
<barcabuona>
but at the same time if Id("x") actually becomes Var(Id("x")) (and i simplify syntax for the user with a function) then ocaml will be able to match the ide within Var() but it will not be able to match ide within Lambda() because the user cannot write the same word to express an ide within a lambda. so he will write Var(Id("x")) and instead shouldve written Id("x")
<barcabuona>
Drup: i think i forgot what a solution is. type ide = string and just ignore that ides and strings are alike for ocaml? (but not for my interpreter nor DSL)
<Drup>
or "type ide = Id of string" and insert the constructor when needed
<barcabuona>
Drup: that's the issue
<barcabuona>
the user needs to insert 2 different constructors to express the same thing: an identifier
<barcabuona>
that's what i want to do btw, type ide = Id of string
<barcabuona>
only thing is i cannot do that and at the same time expect the user to be able to consistently use Id() in the same way
<barcabuona>
or Var(Id()) in the same way for all i care (ill just fix ugly syntax with a function)
<Drup>
then pick the other, and writer your interpreter like that
<barcabuona>
because 1. ocaml cannot directly embed a type in another type, type expr = Int of int | ide) 2. ocaml cannot directly match a type but only constructors
<Drup>
you can change it later
<barcabuona>
like match e with ide is not possible
<barcabuona>
only match e with Id()...
<barcabuona>
but that isnt possible because my interpreter matches expressions not ides
<barcabuona>
so it will have to be something else like match e with Var()
<barcabuona>
Drup: are you saying type ide = string?
<tautologico>
you're writing an interpreter but the user has to enter abstract syntax?
<barcabuona>
i might be overcomplicating this
<tautologico>
can't use a parser?
<barcabuona>
tautologico: my syntax is my own :P
<barcabuona>
nope
<Drup>
barcabuona: yes, you are overcomplicating this
<Drup>
like, a lot
larhat has joined #ocaml
<tautologico>
+1 probably overcomplicating
<barcabuona>
i was saying. i might be overcomplicating this, but i cannot have ocaml interpret ide and string alike when i will have to add functions to String/EString and will need to use ocaml's string type
<Drup>
Yes, the syntax is not absolutely perfect because it's an EDSL .... *shrug*
<barcabuona>
ofc all this is avoidable if i had a parser but i dont so thats out of the question
<barcabuona>
EDSL?
<Drup>
Embedded DSL
<barcabuona>
so i either choose 1. imperfect syntax 2. ocaml cannot distinguish 2 types?
<tautologico>
get something working with whatever syntax, then refine/add ppx etc
<barcabuona>
hmmmm i dunno which to choose....
<Drup>
just choose one, you can change it later ...
<barcabuona>
gotta go eat but thanks for helping me get the issue guys
<barcabuona>
ill choose later...its gonna be rly hard
<barcabuona>
harder than implementing the interpreter probably
<Drup>
I mean, you spend more time pondering which type to use than what it will take you to actually write the interpreter
<tautologico>
this is a kind of procrastination :)
<Drup>
not the good kind
<Drup>
whichever way you choose, it'll take 5 minutes top to switch it, after having implemented everything
yegods has joined #ocaml
yegods has quit [Remote host closed the connection]
yegods has joined #ocaml
yegods has quit [Ping timeout: 258 seconds]
yegods has joined #ocaml
yegods has quit [Remote host closed the connection]
pierpa has joined #ocaml
jao has quit [Ping timeout: 240 seconds]
arj has joined #ocaml
arj has quit [Client Quit]
Mercuria1Alchemi has quit [Ping timeout: 240 seconds]
yegods has joined #ocaml
mengu has joined #ocaml
yegods has quit [Ping timeout: 240 seconds]
fedruantine has joined #ocaml
<barcabuona>
guys i think i got it
<barcabuona>
i choose consistent user syntax
<barcabuona>
and i discovered it could not be done without a hack
<barcabuona>
which is let lambda = ....
<barcabuona>
but then i also wanted to have ide different from string
<barcabuona>
so i just let var = ... (a fix for expr)
<barcabuona>
and therefore my syntax is consistent: var("x"). also ide =/= string for ocaml. it's a half win but i still have got functions to add for each new operator
<barcabuona>
as long as i want consistent user syntax that is
jnavila has quit [Remote host closed the connection]
<barcabuona>
alright screw syntax who cares im not making a new function for every constructor i add!
<barcabuona>
after all syntax is constrained by ocaml anyway soo it has to be this way
<barcabuona>
plus if i were programming in another language such as haskell i might embed types
sh0t has quit [Remote host closed the connection]
nightmared has quit [Ping timeout: 245 seconds]
Simn has joined #ocaml
jao has joined #ocaml
nightmared has joined #ocaml
Simn has quit [Quit: Leaving]
iZsh has quit [Ping timeout: 240 seconds]
iZsh has joined #ocaml
spew has joined #ocaml
kassens has quit [Ping timeout: 240 seconds]
larhat has quit [Quit: Leaving.]
kakadu has joined #ocaml
jmiven has quit [Quit: WeeChat 1.7.1]
TheLemonMan has quit [Quit: "It's now safe to turn off your computer."]
jmiven has joined #ocaml
olibjerd has quit [Ping timeout: 240 seconds]
<barcabuona>
is there a way to define an anonymous function int -> int -> int ?
<barcabuona>
as in 2 parameters
<barcabuona>
function x y -> x+y
<barcabuona>
the only way i found was function (x,y) -> x+y
<companion_cube>
fun x y -> x+y
<barcabuona>
companion_cube: so to pattern match on that i have to do match?
<companion_cube>
yes
<companion_cube>
`function` only works for one argument, sorry
<companion_cube>
although `fun x -> function …` works if you match on the last arg
<barcabuona>
thanks
jbrown has quit [Ping timeout: 258 seconds]
spew has quit [Ping timeout: 255 seconds]
<barcabuona>
can you also help me out with something else? i know im a bit of a pain but it's difficult stuff...i need to extend a function. it is an association between types (eg string->int) and i want to add a new association. It would be something like let newfunction = function "a"->1 | _->oldfunction. now i want to make a function that takes a new binding (function) and adds it to the old function
<barcabuona>
it's kinda like :: but for functions
<Drup>
barcabuona: You don't. Use Map or Hashtbl
AlexDenisov has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
diphuser has quit [Ping timeout: 268 seconds]
Anarchos has joined #ocaml
<barcabuona>
Drup: it does neet to be a function though
<barcabuona>
if im to adhere to theoretical definitions that is
jbrown has joined #ocaml
<Drup>
You can consider a map as a partial function, which should satisfy your theoretical definition :p
<octachron>
barcabuona, and what is the theoretical definition of a function?
<barcabuona>
im not making a super cool new app guys
<barcabuona>
it's an environment
<barcabuona>
and environments are functions: ide -> value
<barcabuona>
i could eventually consider using a list of environments instead of a single environment
<barcabuona>
but the environment is a function and that is it
<barcabuona>
so. i need to extend it...
<Drup>
where does "environments are functions" comes from ?
tane has quit [Quit: Leaving]
<barcabuona>
from a pdf that talks about the origins of making an interpreter
<barcabuona>
so everything is extremely theoretical
<octachron>
barcabuona, most often environment are better implemented with a "val find: env -> ide -> value"
<barcabuona>
and that's why it's so anti-practical
<Drup>
Why do you care exactly ?
<barcabuona>
octachron: interesting
<Drup>
you want extensible partial functions, the way to implement that is a Map, that's it.
<barcabuona>
Drup: i must remain loyal to my pdfs
<barcabuona>
but srsly
<barcabuona>
i cant pattern match on a function
<Drup>
No
<barcabuona>
yet i can do let env' oldenv = function "a"->3 | _->oldenv
<octachron>
barcabuona, that is linear in the number of added function
<barcabuona>
octachron: i do understand that. unless i activate inlining that is
<barcabuona>
or something
<barcabuona>
anyway im not really interested in performance currently
<barcabuona>
only in adhering to the most simple theoretical foundations that i can
<octachron>
barcabuona, the point is that a Map is a much an implementation of a mathematical function than a in-language function
<octachron>
barcabuona, are you going to implement function as relation in a axiomatic set theory ?
<barcabuona>
more or less
<barcabuona>
not really sure about axiomatic set theory but relation is there, set is there too for the time being, theory as well. axiomatic set theory is something i dont recognize
<barcabuona>
but i think you're right anyway. ever seen the notation p[x->5] ?
<barcabuona>
that's what im trying to do
yegods has joined #ocaml
<barcabuona>
extend p with a substituion of x
<Drup>
barcabuona: So, small advice, don't assume you understand a concept just because you recognize some words separately. It doesn't work like that.
mengu has quit [Quit: Leaving...]
<Drup>
Now, the mathematical function is very loose. I'm pretty sure your paper doesn't actually define what it means by function, and just assume something like a dictionnary, where you can add bindings and you can look up definitions
<Drup>
which is exactly what a Map is
<barcabuona>
the usage is similar to that of a dictionary
<barcabuona>
but the definition is very much a function
<barcabuona>
env = ide->value
<barcabuona>
anyway i have no issue with the performance
<barcabuona>
is it not possible to do this?
<barcabuona>
so i need something like extend: ide -> value -> (ide -> value) -> (ide -> value)
freusque has joined #ocaml
<barcabuona>
it may optionally be extend: (ide->value) -> (ide -> value) -> (ide -> value) but i hope for my sanity it doesn't get to that
olibjerd has joined #ocaml
<octachron>
barcabuona, no what you want is much more pratical ide -> value -> env -> env
<octachron>
then the env type is a concrete type that contains the data needed to map ide to value, i.e the val find:env -> ide -> value function
<barcabuona>
octachron: ah yes thank you thats wha ti mean
GomJabbar has left #ocaml [#ocaml]
<barcabuona>
that's getting abit structured though
<barcabuona>
find: env-> ide -> value implies that i need to search
<barcabuona>
while earlier i was just working with plain old pure functions
<barcabuona>
now i need to implement some structure and filter
<barcabuona>
which is not what i wanted to do at all i just wanted to chain together a function
<octachron>
plain old function cannot be extended easily
<octachron>
and you do not need to implement a structure yourself, there is a Map functor is the standard library
<barcabuona>
but what about that example i provided earlier?
<octachron>
which one?
olibjerd has quit [Quit: olibjerd]
freusque has quit [Quit: WeeChat 1.7]
<barcabuona>
>> yet i can do let env' oldenv = function "a"->3 | _->oldenv
<octachron>
barcabuona, sure you can, but them, at best, the compiler will implement this function has a table lookup in the end
<barcabuona>
im not sure i care what the compiler implements it as
<barcabuona>
im interested in being able to express that concept in a functional manner
<barcabuona>
im thinking of this:
<barcabuona>
let env' id val oldenv = function id2-> if id2=id then val else oldenv id2
Anarchos has quit [Quit: Vision[0.9.7-H-20140108]: i've been blurred!]
<octachron>
barcabuona, functional pararadigm is at much about data than functions, there is little point of trying to avoid map/dictionary like this
<octachron>
*as much about data than functions
ontologiae has joined #ocaml
<barcabuona>
octachron: this would be more clear if you could provide an example for both. im not too well versed in ocaml
<barcabuona>
as far as i know using lambdas for this is very natural yet not the optimal way
<barcabuona>
but think of lambda calculus
<barcabuona>
much faster to build functions that map rather than mappings