companion_cube changed the topic of #ocaml to: Discussions about the OCaml programming language | http://www.ocaml.org | OCaml 4.11 release notes: https://caml.inria.fr/pub/distrib/ocaml-4.11/notes/Changes | Try OCaml in your browser: http://try.ocamlpro.com | Public channel logs at http://irclog.whitequark.org/ocaml
<d_bot> <Drup> that's a little bit of a weird question
reynir has joined #ocaml
amiloradovsky has quit [Remote host closed the connection]
amiloradovsky has joined #ocaml
sagax has quit [Quit: Konversation terminated!]
mxns has joined #ocaml
borne has quit [Ping timeout: 240 seconds]
borne has joined #ocaml
mxns has quit [Ping timeout: 272 seconds]
ygrek has joined #ocaml
ygrek has quit [Ping timeout: 240 seconds]
ygrek has joined #ocaml
ygrek has quit [Remote host closed the connection]
dhil has quit [Ping timeout: 240 seconds]
Tuplanolla has quit [Quit: Leaving.]
amiloradovsky has quit [Remote host closed the connection]
<d_bot> <dj charlie> i was listening to the signals and threads podcast
<d_bot> <dj charlie> and one of the compiler maintainers mentioned the amount of times that they fail to get patches upstreamed into ocaml
<d_bot> <dj charlie> it makes me wonder where the disconnect lies in terms of what kind of changes that jane street would try to push up but fail with
<d_bot> <dj charlie> what that would look like
<d_bot> <dj charlie> @Drup
inkbottle has joined #ocaml
zebrag has quit [Ping timeout: 240 seconds]
osa1_ has joined #ocaml
osa1 has quit [Ping timeout: 240 seconds]
mfp has quit [Ping timeout: 264 seconds]
lix has quit [Remote host closed the connection]
mfp has joined #ocaml
mfp has quit [Ping timeout: 246 seconds]
mxns has joined #ocaml
mxns has quit [Ping timeout: 272 seconds]
reynir has quit [Ping timeout: 240 seconds]
reynir has joined #ocaml
mxns has joined #ocaml
aaaaaa has quit [Ping timeout: 240 seconds]
mxns has quit [Ping timeout: 272 seconds]
borne has quit [Ping timeout: 264 seconds]
nullcone has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 260 seconds]
waleee-cl has quit [Quit: Connection closed for inactivity]
shawnw has joined #ocaml
narimiran has joined #ocaml
andreas303 has quit [Remote host closed the connection]
andreas303 has joined #ocaml
vicfred_ has joined #ocaml
vicfred has quit [Ping timeout: 260 seconds]
vicfred_ has quit [Quit: Leaving]
mxns has joined #ocaml
mxns has quit [Ping timeout: 256 seconds]
sagax has joined #ocaml
decentpenguin has quit [Read error: Connection reset by peer]
decentpenguin has joined #ocaml
osa1_ is now known as osa1
reynir has quit [Quit: WeeChat 2.3]
chripell has quit [Remote host closed the connection]
chripell has joined #ocaml
reynir has joined #ocaml
osa1 has quit [Quit: osa1]
osa1 has joined #ocaml
nullcone has quit [Quit: Connection closed for inactivity]
<d_bot> <craigfe> @Cyclomatic Complexity. It's easier to deal with the open type inside the GADT itself:
<d_bot> <craigfe> ```ocaml
<d_bot> <craigfe> type foo = [`Foo]
<d_bot> <craigfe> type bar = [`Bar]
<d_bot> <craigfe> type wee = [`Wee]
<d_bot> <craigfe>
<d_bot> <craigfe> type 'a ast =
<d_bot> <craigfe> | Foo : [> foo] ast
<d_bot> <craigfe> | Bar : [> bar] ast
<d_bot> <craigfe> | Wee : [> wee] ast
<d_bot> <craigfe>
<d_bot> <craigfe> type a = [foo | bar] ast
<d_bot> <craigfe> type b = [bar | wee] ast
<d_bot> <craigfe>
<d_bot> <craigfe> let a_to_b : a -> b = function
<d_bot> <craigfe> | Foo -> Bar
<d_bot> <craigfe> | Bar -> Wee
<d_bot> <craigfe> ```
<d_bot> <craigfe>
<d_bot> <craigfe> Hopefully that does what you want.
<d_bot> <craigfe> It seems that your issue is quite similar to this one that I answered a while back: https://discuss.ocaml.org/t/problem-with-subtyping-in-polymorphic-variant-in-gadt/6650/2
Haudegen has joined #ocaml
<d_bot> <Cyclomatic Complexity> That looks like exactly what I want, thanks!
<d_bot> <Cyclomatic Complexity> It is, double thanks:D
bartholin has joined #ocaml
borne has joined #ocaml
Tuplanolla has joined #ocaml
mxns has joined #ocaml
aaaaaa has joined #ocaml
berberman_ has joined #ocaml
berberman has quit [Ping timeout: 260 seconds]
mxns has quit [Ping timeout: 272 seconds]
bjorkintosh has quit [Ping timeout: 256 seconds]
bjorkintosh has joined #ocaml
hnOsmium0001 has quit [Quit: Connection closed for inactivity]
reynir has quit [Quit: WeeChat 2.3]
reynir has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 256 seconds]
<d_bot> <Cyclomatic Complexity> Sooo.....
<d_bot> <joris> Don't do that
<d_bot> <joris> I mean simple case like this using gadt as a type witness work but as soon as you introduce subtyping into gadt you are on direct track to nightmare level debugging
<d_bot> <Cyclomatic Complexity> The next thing I want is something like the following:
<d_bot> <Cyclomatic Complexity> ```ocaml
<d_bot> <Cyclomatic Complexity> type foo = [`Foo]
<d_bot> <Cyclomatic Complexity> type bar = [`Bar]
<d_bot> <Cyclomatic Complexity> type wee = [`Wee]
<d_bot> <Cyclomatic Complexity>
<d_bot> <Cyclomatic Complexity> type void = |
<d_bot> <Cyclomatic Complexity>
<d_bot> <Cyclomatic Complexity> type ('condition , 'a , 'b) option =
<d_bot> <Cyclomatic Complexity> | Some : 'a -> ('a , 'a) option
<d_bot> <Cyclomatic Complexity> | None : ('a , 'b) option
<d_bot> <Cyclomatic Complexity>
<d_bot> <Cyclomatic Complexity> type 'a ast =
<d_bot> <Cyclomatic Complexity> | Foo : {
<d_bot> <Cyclomatic Complexity> foo_1 : ('a :> [foo_1] , int , void) option ;
<d_bot> <Cyclomatic Complexity> foo_2 : ('a :> [foo_2] , string , void) option ;
<d_bot> <Cyclomatic Complexity> } -> [> foo] ast
<d_bot> <Cyclomatic Complexity> | Bar : [> bar] ast
<d_bot> <Cyclomatic Complexity> | Wee : [> wee] ast
<d_bot> <Cyclomatic Complexity>
<d_bot> <Cyclomatic Complexity> type a = [foo | foo_1 | bar] ast
<d_bot> <Cyclomatic Complexity> type b = [bar | wee] ast
<d_bot> <Cyclomatic Complexity> type c = [foo | foo_2 | wee] ast
<d_bot> <Cyclomatic Complexity>
<d_bot> <Cyclomatic Complexity> let a_to_b : a -> b = function
<d_bot> <Cyclomatic Complexity> | Foo _ -> Bar
<d_bot> <Cyclomatic Complexity> | Bar -> Wee
<d_bot> <Cyclomatic Complexity>
<d_bot> <Cyclomatic Complexity> let x : a = Foo { foo_1 : Some 42 ; foo_2 : None }
<d_bot> <Cyclomatic Complexity> let y : c = Foo { foo_2 : Some "fortytwo" ; foo_1 : None }
<d_bot> <Cyclomatic Complexity> ```
<d_bot> <Cyclomatic Complexity> Basically, I want the conditional type to resolve to the former type if it is true, and to the latter type if it is false
<d_bot> <Cyclomatic Complexity> I am interested in trying, especially if I can wrap it by some syntactic sugar after, so that users don't have to see it
<d_bot> <joris> well, very good luck to you. You are venturing into dark corners of the type system
<d_bot> <Cyclomatic Complexity> yup. i did so a couple of times and got burnt already
<d_bot> <octachron> My experience is that you cannot really hide the complexity of using type variables to do computations to the users: at some point, the computational type variables will appear in errors.
<d_bot> <Drup> @Cyclomatic Complexity `'a :> [foo_1] ? int : void)` does that mean "if 'a is a subtype of foo_1, then the type is int, else it's void" ? If that's what you want the answer is "No"
<d_bot> <Drup> It's ocaml, not typescript 😄
aaaaaa has quit [Ping timeout: 256 seconds]
<d_bot> <Drup> You can't write tests in the type system. You can impose conditions, which is very different, by using another GADT
<d_bot> <octachron> Well with type conjunctions in polymorphic variants, you can kind of write some tests (not those one though); if you want to turn on the eldritch horror level of complexity and error messages. And if you are fine with your code being broken by new versions of the compiler. And dune.
<d_bot> <Drup> mixing GADTs and polyvars are a mistake anyway
<d_bot> <joris> what does it even mean btw 'a :> [foo_1] ? int : void ?
<d_bot> <Drup> it's a typescript feature
<d_bot> <Drup> you can do tests in the typesystem there
<d_bot> <joris> ok, but it does not parse into ocaml right ?
<d_bot> <Drup> of course not
<d_bot> <Cyclomatic Complexity> @Drup It's pseudo-code yeah
<d_bot> <Cyclomatic Complexity> That's the end-result I want
<d_bot> <Drup> You'll need to find another way 🙂
<d_bot> <joris> maybe what you want is fstar
<d_bot> <Cyclomatic Complexity> That is literally what I am asking for
<d_bot> <Drup> What's the property you want to express ?
<d_bot> <Drup> Let's drop the toy example for once, what is the domain you are trying to model, and what globaly property do you want on it
<d_bot> <Cyclomatic Complexity> So, in general, I want to have a big AST, which contains all variant cases and record fields
<d_bot> <Cyclomatic Complexity> Then, I want to define sub ASTs, that only have some variant cases and some record fields. The `some variant cases` has been addressed by the first thing. Now I'm looking for the `some field cases`
<d_bot> <joris> just to put things into perspective, what i am doing right now is try to figure why lsp is totally unusable on a file where i abused GADT and subtyping
<d_bot> <joris> (lsp takes 5 to 10s to react to change)
<d_bot> <Cyclomatic Complexity> > thanks. i did so a couple of times and got burnt already, so I am knowingly doing this
<d_bot> <Cyclomatic Complexity> 🤷
<d_bot> <Drup> @Cyclomatic Complexity are you sure defining multiple ASTs is not strictly simpler ?
<d_bot> <Cyclomatic Complexity> yes.
<d_bot> <Cyclomatic Complexity> i might have something like more than half a dozen stages
<d_bot> <Cyclomatic Complexity> and now, we are moving to codegens (ppx most notably) for a lot of things, but this is quite bad, and i would much prefer a solution within the language
<d_bot> <Cyclomatic Complexity> where i define the JSON formats and pretty printers once and for all
<d_bot> <Cyclomatic Complexity> rather than duplicating it on all intermediary stages, and using ppxs (where i have to make sure the same annotations are used everywhere for compatibility reasons)
<d_bot> <Drup> wait, it's for some JSON format ? Isn't dynamic safety more suitable ?
<d_bot> <Cyclomatic Complexity> no, those are ASTs, that I serialize in JSON, among other things
<d_bot> <reynir> just fyi, this channel is bridged with IRC, and long code snippets appear as many single messages, one for each line
<d_bot> <joris> isn't it easier to have functors with smart constructors and visitors ?
<d_bot> <Cyclomatic Complexity> @reynir ouch. what's the best way to deal with it?
<d_bot> <Cyclomatic Complexity> not sure what you have in mind, i'm interested.
<d_bot> <Cyclomatic Complexity> i just want to avoid having to redefine all serializers, record helpers, variant helpers, and making sure those are defined the same way in all stages
<d_bot> <reynir> Ideally, the bridge should use a pastebin :D but otherwise you can pastebin the code yourself or use a different channel. It's not optimal...
<d_bot> <Drup> honestly, I would just do the legwork
<d_bot> <Drup> it's boring, but it's better than trying and failing at making knots in your brain
<d_bot> <Drup> the UX will be better too, especially for programmers who are not fluent in type magic
<d_bot> <joris> you define a single AST type, but to restrict usage for each subast you expose api to destruct and construct each case with restrictions, and you can use modules inclusion to factor
<d_bot> <joris> but i would just define multiple ast and convert, or put asserts tbh
<d_bot> <Drup> there is a sort-of-solution
Enjolras has joined #ocaml
<d_bot> <Cyclomatic Complexity> The problem is not boringness
<d_bot> <Cyclomatic Complexity> The problem is modifying a case in the ast takes three hours
<d_bot> <Cyclomatic Complexity> And so routine maintenance operations are delayed because of how much time they take
<d_bot> <Cyclomatic Complexity> I am not even talking about stuff that we have *not* implemented because of this
<d_bot> <Cyclomatic Complexity> Like, substitution on all passes
<d_bot> <Drup> You could probably write templated-ish code using a ppx
<d_bot> <Cyclomatic Complexity> I'll try it, this is interesting
<d_bot> <Cyclomatic Complexity> PPX doesn't solve. even if it does directed code gen for stuff like JSONs, you still have to put your annotations everywhere, make sure those are the same. it also does not deal with advanced stuff like substitutions.
<d_bot> <Cyclomatic Complexity> @joris Not sure what you mean here
<d_bot> <Drup> No, I mean write your own ppx that takes a single file where you have annotation such as `[@ast 1, 2, 5]` on types and expressions, and you derive your 6 implementation from that
<d_bot> <Drup> You'll probably have to write the converters somehow
<d_bot> <Cyclomatic Complexity> @Drup hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
<d_bot> <Cyclomatic Complexity> not sure what you mean by "the converters"
<d_bot> <Drup> from ast1 to 2, etc
<d_bot> <Cyclomatic Complexity> oh ye ofc
<d_bot> <Cyclomatic Complexity> those are the passes, very localized, so it's ok
<d_bot> <Cyclomatic Complexity> the problem is mostly to rederive everything linked to ASTs every time
<d_bot> <Cyclomatic Complexity> that seems quite unmaintainable though tbh
<d_bot> <Drup> Another option: you write your AST in the style `(a,b,c,d,e,f) ast`, where `a` to `f` are booleans, and you annotate each constructor by saying if the constructor is acceptable or unnaceptable for each pass
<d_bot> <Cyclomatic Complexity> how so? that's what I wanted to try
<d_bot> <Cyclomatic Complexity> but for fields, rather than constructors
<d_bot> <Drup> and you have `type ast1 = (t, void, void, void ....) ast`
<d_bot> <octachron> It is generally easier to do in a closed universe where each of your stage is explicitly defined and avoid polymorphic variants at the type level.
<d_bot> <Cyclomatic Complexity> @Drup how do you have boolean for record fields?
<d_bot> <Drup> `type t = T and type void = |`
<d_bot> <joris> @Drup last time i tried that, i ended up with 30 type parameters, and code became litterally unreadable
<d_bot> <Cyclomatic Complexity> (and i am stupid, it is also much better to use booleans for cases, than this polymorphism thingy)
<d_bot> <joris> not to mention type error, even if you name you type diffferently for each parameter, and not just universal bool flag
<d_bot> <Drup> @joris If you do it by feature, it's a mess, but @Cyclomatic Complexity seems to have 6 well defined cases
<d_bot> <Drup> adding another AST is going to be a nightmare though
<d_bot> <Cyclomatic Complexity> ye. i think i prefer the functor solution so far
<d_bot> <Drup> the templated PPX is a the best idea for me.
<d_bot> <Cyclomatic Complexity> @Drup Do you have a concrete example of templated PPX?
<d_bot> <Drup> it should be not so difficult to extend nor define
<d_bot> <joris> you might be able to factor out the type outside of the module, like you define your concrete ast with a single param, and you define a separate module with all type constructor
<d_bot> <joris> but yeah, it's only a small win.
<d_bot> <Drup> concrete example, I'm not sure, we have something in this spirit in tyxml, but doing reflection
<d_bot> <Cyclomatic Complexity> hmm. might be more complicated than what i have in mind. if you have a link, i'll take it though
<d_bot> <Drup> (it won't really be a ppx by the way, just takes an ocaml file and return multiple ocaml files)
<d_bot> <Drup> The main bit of the implem is here: https://github.com/ocsigen/tyxml/blob/master/syntax/reflect/reflect.ml
<d_bot> <Drup> In the tyxml code, you have annotations like this that guide it when necessary: https://github.com/ocsigen/tyxml/blob/master/lib/html_sigs.mli#L552-L556
<d_bot> <Drup> Anyway, for you it would just read an ocaml file with some annotations and output 6 versions as ocaml files where the parts have been filtered according to the annotations
<d_bot> <Drup> (You could prototype it with cppo/optcomp, before moving to a tech that actually works :p)
mfp has joined #ocaml
<d_bot> <Cyclomatic Complexity> thanks!
<d_bot> <Cyclomatic Complexity> that sounds about right
<d_bot> <Drup> By curiosity, what's the actual use case ?
ldbeth has joined #ocaml
<ldbeth> good evening
dhil has joined #ocaml
ldbeth has quit [Quit: ERC (IRC client for Emacs 27.1)]
osa1_ has joined #ocaml
osa1 has quit [Ping timeout: 256 seconds]
osa1_ is now known as osa1
steenuil has quit [Ping timeout: 256 seconds]
steenuil has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 264 seconds]
raver has quit [Remote host closed the connection]
sagax has quit [Read error: Connection reset by peer]
mxns has joined #ocaml
mxns has quit [Ping timeout: 272 seconds]
vicfred has joined #ocaml
waleee-cl has joined #ocaml
tane has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 265 seconds]
borne has quit [Ping timeout: 264 seconds]
borne has joined #ocaml
mxns has joined #ocaml
davs has joined #ocaml
raver has joined #ocaml
hnOsmium0001 has joined #ocaml
urek has joined #ocaml
urek has quit [Quit: urek]
urek has joined #ocaml
borne has quit [Ping timeout: 240 seconds]
borne has joined #ocaml
sagax has joined #ocaml
narimiran has quit [Ping timeout: 256 seconds]
narimiran has joined #ocaml
webshinra has quit [Remote host closed the connection]
TheLemonMan has joined #ocaml
webshinra has joined #ocaml
Anarchos has joined #ocaml
borne has quit [Quit: WeeChat 2.9]
borne has joined #ocaml
bartholin has quit [Quit: Leaving]
mxns has quit [Ping timeout: 244 seconds]
mxns has joined #ocaml
davs has quit [Quit: leaving]
reynir has quit [Ping timeout: 256 seconds]
reynir has joined #ocaml
<d_bot> <Bluddy> ocamlearlybird is just for bytecode compilation, right?
aaaaaa has joined #ocaml
jnavila has joined #ocaml
berberman has joined #ocaml
borne has quit [Ping timeout: 244 seconds]
berberman_ has quit [Ping timeout: 264 seconds]
reynir has quit [Ping timeout: 260 seconds]
reynir has joined #ocaml
<d_bot> <EduardoRFS> yup
<d_bot> <Bluddy> thanks
vicfred has quit [Ping timeout: 246 seconds]
mxns has quit [Ping timeout: 272 seconds]
oni-on-ion has quit [Read error: Connection reset by peer]
mxns has joined #ocaml
oni-on-ion has joined #ocaml
<d_bot> <cemerick> I'm looking for a "syntaxful" reference OCaml source file, i.e. one file that includes close to all of OCaml's valid syntax. I thought I might find one floating around somewhere in ocamlformat's repo, but I haven't found it yet. Anyone know of such a thing?
<d_bot> <cemerick> (as for "why??", I'd like to golf around with ocamlformat options, and having everything that might be affected in a single buffer would be helpful)
vicfred has joined #ocaml
<d_bot> <Drup> @cemerick you might find some of you want under `testsuite/tests/parsing/`
<cemerick> ah, in ocaml/ocaml
* d_bot <cemerick> promises to stop switching between irc and discord :-P
<d_bot> <cemerick> @Drup pity it's spread across N files
<d_bot> <craigfe> `parsetree/source.ml` is pretty huge
<d_bot> <craigfe> that one is in the OCamlFormat test suite too, and seems to catch most changes when I've worked on it
<d_bot> <Drup> @cemerick well, you can just concatenate ...
narimiran has quit [Ping timeout: 256 seconds]
nullcone has joined #ocaml
<d_bot> <inkbottle> Can `ocaml-lsp-server` generate `.mli` file?
madroach has quit [Ping timeout: 256 seconds]
<d_bot> <inkbottle> In the past I've used `dune exec -- ocaml-print-intf bin/hello.ml`. But now I have `dune` called through `esy`.
<d_bot> <inkbottle> That line `esy x 'dune exec -- ocaml-print-intf example/hello_world/main.ml'` had not produced output in `stdout`, nor to be found by `find . -type f -cmin -8`.
Jesin has quit [Quit: Leaving]
madroach has joined #ocaml
Anarchos has quit [Ping timeout: 265 seconds]
<d_bot> <inkbottle> `esy x 'ocamlc -i example/hello_world/main.ml'` isn't working, neither.
<d_bot> <inkbottle> It doesn't fail, only it doesn't produce output.
<d_bot> <inkbottle> in contrast, `ocamlc -i example/hello_world/main.ml` fails, for the obvious reason it doesn't find the modules.
TheLemonMan has quit [Quit: "It's now safe to turn off your computer."]
<d_bot> <craigfe> @inkbottle : There's an unreleased "ocamllsp/inferIntf" that I've heard about (https://github.com/ocaml/ocaml-lsp/pull/314)
<d_bot> <craigfe> Haven't tried it though
<d_bot> <inkbottle> Thanks for the pointer.
<d_bot> <joris> From cmdline I find the easier way is to use cmi2mli tool
<d_bot> <joris> No need to figure out build options which can be tricky with dune
Jesin has joined #ocaml
<d_bot> <joris> You just find cmi and that's it everything is self contained
<d_bot> <inkbottle> Following your lead, I first have to convince `dune build -p #{self.name}` to build bytecode, and not just native.
<d_bot> <joris> You mean me? Afaik cmi are always built they are used for native comp too?
<d_bot> <inkbottle> Yeah, just what I'm reading. Looking for them now.
<d_bot> <inkbottle> Found them.
<d_bot> <joris> They are in hidden folder inside _build
<d_bot> <joris> I have a crude vim command to generate mli with that until ocamllsp supports is mature very handy
borne has joined #ocaml
<d_bot> <inkbottle> And there it is. (`cmi2mli` really spells `cmitomli`, I think.)
<d_bot> <inkbottle> It is very convenient because it doesn't have to depend on "every thing else".
<d_bot> <inkbottle> Like, should I have `ocaml-lsp` in my "default opam switch" or, in my `esy` sandboxed switch? (I can put it in `devDependencies`, I can.)
<d_bot> <inkbottle> But then, do I call `emacs` through `esy x emacs hello.ml`?
<d_bot> <inkbottle> For the present it is in my "default".
jnavila has quit [Quit: Konversation terminated!]
urek has quit [Ping timeout: 246 seconds]
urek has joined #ocaml
sagax has quit [Remote host closed the connection]
Serpent7776 has quit [Quit: leaving]
ygrek has joined #ocaml
tane has quit [Quit: Leaving]
<d_bot> <cemerick> @craigfe yeah, source.ml looks pretty good, thanks! https://github.com/ocaml-ppx/ocamlformat/blob/master/test/passing/source.ml
mxns has quit [Ping timeout: 264 seconds]
urek__ has joined #ocaml
urek has quit [Ping timeout: 272 seconds]
mxns has joined #ocaml
mxns has quit [Ping timeout: 256 seconds]
mxns has joined #ocaml
dhil has quit [Ping timeout: 272 seconds]
amiloradovsky has joined #ocaml