<astronavt>
how the heck do i get the current time zone offset?
<astronavt>
i was able to get as far as `let tz = force Timezone.local` with the jane street lazy and timezone libraries, but i have no idea if even that is correct
<astronavt>
well this is good enough for what i need, although i'm still not sure how to actually access the data in these data structures: Time.to_string_abs (Time.now ()) (Lazy.force Time.Zone.local)
<astronavt>
there's no "structured" date/time object in Core? Unix has it, but idk if it's bad practice to mix libraries like that
Leonidas_ has joined #ocaml
tristanC_ has joined #ocaml
<astronavt>
ah, this does the same: Time.to_string (Time.now ())
mxns has quit [Ping timeout: 260 seconds]
eternalgeek[m] has quit [*.net *.split]
smondet[m] has quit [*.net *.split]
angerman has quit [*.net *.split]
artart78 has quit [*.net *.split]
tristanC has quit [*.net *.split]
Leonidas has quit [*.net *.split]
artart78 has joined #ocaml
angerman has joined #ocaml
eternalgeek[m] has joined #ocaml
<hackinghorn>
eh, so I cannot modify one element of a list without creating a whole new list?
smondet[m] has joined #ocaml
mxns has joined #ocaml
vicfred has quit [Quit: Leaving]
<hackinghorn>
I have this problem, I have a List of string, I want to find the place where some element is "x", and change the element after it into "y"
hosewiejacke2 has joined #ocaml
<astronavt>
hackinghorn: maybe zip the list with its own tail?
hosewiejacke2 has quit [Client Quit]
<d_bot>
<dj charlie> guys, how do you print the sexp form of the bytecode?
<d_bot>
<dj charlie> could've sworn that was an option
<d_bot>
<dj charlie> having trouble showing it off
<hackinghorn>
astronavt, eheh maybe
<astronavt>
hackinghorn it's a classic idiom in python, at any rate
<d_bot>
<dj charlie> found the assembly option but not the sexp one, could've sworn that was an option 🤔
narimiran has joined #ocaml
mxns has quit [Ping timeout: 258 seconds]
<astronavt>
hackinghorn: let notfirst (x :: xs) = xs ;; let notlast x = List.filteri (fun i _ -> i != ((List.length x) - 1)) x ;; let ll = List.combine (notlast l) (notfirst l) in map _____ ll ;;
<astronavt>
im sure theres a better way to do it but that's what my inept self would do
<hackinghorn>
astronavt, ah thanks, let me check that
<d_bot>
<EduardoRFS> So with this we should be able to run new merlin on old OCaml right?
mxns has joined #ocaml
mxns has quit [Ping timeout: 258 seconds]
Goodiec has joined #ocaml
webshinra_ has joined #ocaml
bartholin has joined #ocaml
webshinra has quit [Ping timeout: 260 seconds]
worc3131 has joined #ocaml
nullcone has quit [Quit: Connection closed for inactivity]
l1x has quit [Quit: Connection closed for inactivity]
[mark] has quit [Quit: Connection closed]
mxns has joined #ocaml
mxns has quit [Ping timeout: 250 seconds]
jbrown has quit [Ping timeout: 260 seconds]
dhil has joined #ocaml
jbrown has joined #ocaml
mxns has joined #ocaml
hackinghorn has quit [Quit: Leaving]
mxns has quit [Ping timeout: 258 seconds]
tane has joined #ocaml
l1x has joined #ocaml
worc3131 has quit [Ping timeout: 260 seconds]
zebrag has joined #ocaml
conjunctive has quit [Quit: Connection closed for inactivity]
serif[m] has joined #ocaml
zebrag has quit [Quit: Konversation terminated!]
zebrag has joined #ocaml
<d_bot>
<JuiceVodka> hey i got a problek with trying to use ocaml with the jupyter notebook extension for wscode has anyone had a similar problem?
hackyhacker has joined #ocaml
mxns has joined #ocaml
mxns has quit [Ping timeout: 252 seconds]
nullcone has joined #ocaml
<hackyhacker>
Hello I created a simple programming language in OCaml where during the evaluation it is useful to convert variable names to integers (De Bruijn indexes).
<hackyhacker>
So I made a parameterized type for my terms where the argument can be int or string
<hackyhacker>
but now when trying to make a polymorphic function to print terms I don't know how to go about it
<hackyhacker>
if I could do something like match on the type parameter I could make it work
<hackyhacker>
Do I need to use modules for this or how should I go about it?
<d_bot>
<Cyclomatic Complexity> You might want to look into GADTs
<hackyhacker>
Ah thank you! :)
Haudegen has quit [Quit: Bin weg.]
<d_bot>
<Cyclomatic Complexity> 👌
<astronavt>
@darrenldl thanks, I will check it out! One gets spoiled with nice "datetime" datatypes. I have been messing around with Crystal as well recently, and datetimes are structured exactly the way you'd would want it; basically a struct with hours mins seconds etc, and first class timezone support. Meanwhile I still can't for the life of me figure out how to actually get the numerical value of the offset out of a Time.Zone thing, apart from parsing i
<d_bot>
<darrenldl> 0.2.0 will ship with nanosecond precision, if that is useful then you might want to wait a bit. it is meant to be a reasoning toolkit and being also a calendar library was not its original plan, but the date time component should be comparable to other libs in other langs. time zone db is built in, and would work cross platform, if that is close to what you were thinking in terms of first class support. i'll check out Crystal's
waleee-cl has joined #ocaml
<astronavt>
yeah that sounds perfect
<astronavt>
if you are looking for other examples of prior art, i use and enjoy the "pendulum" library in Python too
<d_bot>
<darrenldl> ooo thanks, i havent encountered that yet somehow, more reference points~
<d_bot>
<darrenldl> i'll note that timere's format string system seems nicer than crystal stdlib's, albeit less complete for now
zebrag has quit [Quit: Konversation terminated!]
zebrag has joined #ocaml
artart78 has quit [Ping timeout: 260 seconds]
mxns has joined #ocaml
<d_bot>
<darrenldl> i have reservations about design of pendulum and crystal stdlib time, but i digress
mxns has quit [Ping timeout: 260 seconds]
mxns has joined #ocaml
mxns has quit [Ping timeout: 258 seconds]
<octachron>
@hackyhacker, rather than a GADT, a simpler way is to give a printer for the "argument" as an argument to the global printer, e.g. `let pp pp_elt ppf term = ... `
<hackyhacker>
I think I've got it with working with GADTs but the syntax is quite ugly
<hackyhacker>
do you mean make a sort of printer object that you pass things to?
<hackyhacker>
I don't really understand what you're suggesting.
<octachron>
From your description, you have a parametric type `'a t`, and speficic instance can be either `int term` or `string term`?
<hackyhacker>
That's right
<octachron>
then you can build up a term printer as a function `'a printer -> 'a term printer`
<hackyhacker>
I have term defined as ``type 'a term = TVar of 'a | ...``
shawnw has quit [Ping timeout: 240 seconds]
<hackyhacker>
the ... are other constructors that don't use 'a
<hackyhacker>
Is the advantage of the printer is that I don't have to pass a type around all the time?
<octachron>
The advantage is that you don't need to resort to GADTs (and all the GADT-induced complexity) to implement some simple polymorphism
<hackyhacker>
Yes it looks a lot simpler! Thank you
Haudegen has joined #ocaml
<hackyhacker>
What does elt stand for in pp_elt?
mxns has joined #ocaml
<octachron>
element. It could be "leaf", "atom", "that elementary thing that I don't want to invent a name for"
<hackyhacker>
Thanks for your help sir! This looks way neater than a GADT indeed.
mxns has quit [Ping timeout: 258 seconds]
zebrag has quit [Quit: Konversation terminated!]
mxns has joined #ocaml
zebrag has joined #ocaml
mxns has quit [Ping timeout: 240 seconds]
<astronavt>
@darrenldl please do digress, i am very interested
mxns has joined #ocaml
mxns has quit [Ping timeout: 258 seconds]
<d_bot>
<darrenldl> for crystal lang: it reads like it insists date time always maps to exactly one unique time point on the utc timeline, which isn't always the case (DST)
<d_bot>
<darrenldl> for first case, timere refuses to give a string interpretation of the time zone offset if you do `Timere.Date_time.to_string`, `to_timestamp` yields a variant type distinguishing between the the non-ambiguous and ambiguous cases
<d_bot>
<darrenldl> for the latter case, `Date_time.make` would simply fail - you cannot construct a `Date_time.t` which does not map to anything to the UTC timeline
<d_bot>
<darrenldl> (this design decision was inspired by chrono-tz from the rust community, and i believe i spotted something similar when examining one of janestreet's lib somewhere...)
<d_bot>
<darrenldl> sorry i forgot to clarify: second case corresponds to when DST starts, jumping from 2am to 3am, i.e. 4th Oct 2:30am does not exist, but crystal is fine with constructing it unless i'm not using crystal correctly
[mark] has joined #ocaml
zebrag has quit [Quit: Konversation terminated!]
zebrag has joined #ocaml
<companion_cube>
oh, are you also coding in crystal?
<astronavt>
@darrenldl very interesting. that's quite an endorsement for timere :)
<astronavt>
that said, my frustrations with ocaml time handling were more related to "how the heck do i actually do stuff and where are the docs"
<astronavt>
is there a "timere-preferred" way to construct an RFC-3339-style timestamp? like what crystal's Time#to_s emits
<astronavt>
or do i just construct it manually with eg. Printf.sprintf ?
jbrown has quit [Quit: Leaving]
jbrown has joined #ocaml
neiluj has joined #ocaml
neiluj has joined #ocaml
Tuplanolla has joined #ocaml
zebrag has quit [Quit: Konversation terminated!]
zebrag has joined #ocaml
Goodiec has quit [Ping timeout: 240 seconds]
Haudegen has quit [Quit: Bin weg.]
mxns has quit [Ping timeout: 240 seconds]
tjammer[m] has quit [Quit: Idle for 30+ days]
mxns has joined #ocaml
olle has quit [Ping timeout: 252 seconds]
<d_bot>
<darrenldl> companion_cube: if you were asking me then nop, just fired up their online repl and went into their docs
<d_bot>
<darrenldl> (or the relevant pretty printers)
<d_bot>
<darrenldl>
<d_bot>
<darrenldl> there are some (small) inconsistencies around the API which I haven't gotten to yet as I'm still trying to get timere 0.2.0 to pass the fuzzing pipeline
<oriba>
Would it make sense to parse XML (big files) with GADTs?
<companion_cube>
what do you mean?
<oriba>
asked on GADTs yesterday. one answer was: not to use for compilers.
narimiran has quit [Ping timeout: 240 seconds]
<oriba>
not sure if there are certain performance problems
<oriba>
on the other hand on jane street blog, they mentioned, GADTss can be used to make code efficient (regarding mem usage)
<companion_cube>
Xml can be represented with like a handful of constructors
<oriba>
the opinions seem to differ
<companion_cube>
no sure what you mean
<oriba>
but aren't GADTs better for expressing the data and the operations?
<oriba>
or does that not add any advantages?
<oriba>
I think about someting like a dsl for transforming xml
<companion_cube>
for the XML AST, it's 100% useless
<companion_cube>
for a DSL, I don't know, maybe?
White_Flame has quit [Ping timeout: 265 seconds]
<d_bot>
<EduardoRFS> I'm interested why the concern of GADTs and compilers?
<oriba>
me too. I shoukld have asked it yeasterday
<oriba>
dh`: yesterday you wrote: "(note: I don't actually recommend doing this in a compiler or interpreter)" regarding GADTs
<oriba>
can you exlain your opinion on that?
<companion_cube>
I'd say the same, representing invariants of an AST with GADTs is a lot of pain for quite little gain
<d_bot>
<rgrinberg> Indeed. It's even too painful in dependently typed languages. Where one can express even stronger invariants about an AST
olle has joined #ocaml
<olle>
Example of data-structure that works best with GC?
<Drup>
graphs.
<companion_cube>
even trees, in many cases
<olle>
Drup: Can be done with regions
<Drup>
ahahah, graphs with regions
<olle>
?
<olle>
Not good?
<Drup>
no, not good :)
<olle>
Why?
tane has quit [Quit: Leaving]
<Drup>
you can look at the numerous discussions about doing graphs in rust for a glimpse
<olle>
Rust has no regions
<Drup>
actually, it kinda does
<olle>
Well
<olle>
Regions with enforced ownership != regions without ownership
<Drup>
Ownership is a way to loosen the traditional region restrictions, so not having ownership is worse
<olle>
Huh?
<olle>
Region in C is more strict than in Rust?
<olle>
Assuming region = memory pool, kind of
<Drup>
that's ... not at all what regions are
<olle>
ffs
<olle>
The I'll rephrase the question
<Drup>
(arguably, there are probably different use of "regions", it's a bit overloaded)
<olle>
Example of data-structure that works better with GC than with memory pools or stack alloc?
<olle>
= unknown lifetime and unknown size
<olle>
can't think of any :d
<Drup>
well, kinda still graphs, especially when used functionally
<olle>
^^
<olle>
Graphs in a use-case which is not contained to a specific algorithm, maybe. Hm.
<Drup>
(functional data structures in general, I would guess)
<olle>
Syntax tree, maybe
<companion_cube>
olle: regions are good… except you collect all or nothing, I think?
<companion_cube>
so it's like having graphs without any GC, until you get rid of the whole graph
<olle>
Regions/memory pool is known lifetime, unknown size
<olle>
Sometimes, that's what you want
<olle>
Or so I've heard ^^
<companion_cube>
so that works only for a graph of known lifetime
<olle>
Yes, like A* algo
<companion_cube>
but you were asking about cases where GC is better
<olle>
Yep
<companion_cube>
so, any case where the graph doesn't have a known lifetime.
<Drup>
I mean, in general all those things fail appart when you have to *return* structures, and not just pass them down.
<olle>
Drup: No, you can pass the region around
<olle>
region/pool
<olle>
Or copy value types :(
<companion_cube>
sounds like someone doesn't want to hear the answers to his question
<olle>
;)
<olle>
No really, it's for an article about locality kinds.
<companion_cube>
people who argue that pools are good enough™ (say… Jon Blow) tend to work in fields like video games, where, sure, most stuff lives forever or for one frame
<companion_cube>
and then they overgeneralize
<olle>
I'm absolutely not saying pools are good enough. They're only good when you KNOW, at time of writing, the lifetime but not the size.
<d_bot>
<rgrinberg> OCaml's GC also assumes that things either live forever or for one frame 😉
<companion_cube>
@rgrinberg: can you display the FPS in dune, please?
<d_bot>
<rgrinberg> Why are GC's good for graphs? One has to mess around with weak pointers to get reasonable behavior for gcing parts of the graph
raver has quit [Read error: Connection reset by peer]
<companion_cube>
not if you only want to collect inaccessible components
<companion_cube>
I think Drup is thinking, like me, about ASTs
<companion_cube>
(which are almost always graphs in practice)
<olle>
Yeah, AST is a good example
<olle>
Global lifetime, unknown size.
<d_bot>
<rgrinberg> Sure, AST is simple, acyclic and usually static. The kind of graphs that pop up in FRP are quite painful to GC tho
<olle>
Yes, you could also make the argument that AST does not need to be collected ^^
<d_bot>
<rgrinberg> @companion_cube in dune there's no frame unit related to time, but we can certainly define wrt to loading rules in a directory. It would make a lot of sense to clear everything allocated once the rules are loaded for a dir
<companion_cube>
ASTs are not necessarily acyclic
<companion_cube>
OCaml's typedtree is not, and for a ML it generally will be at least a DAG, not a tree
<d_bot>
<rgrinberg> It's still a super static pattern. Once the graph it is constructed, you rarely mutate it
<olle>
Someone suggested web server data as a use-case of infinite lifetime but unknown size that still needs to be collected.
<Drup>
rgrinberg: the AST is, the types (computed by inference) are not. That's a rather niche thing though
<olle>
(E.g. cached pages)
<d_bot>
<rgrinberg> Servers are indeed a bit tricky. Things either live forever and can be allocated in advance, or are somehow tied to the lifetime of clients
<companion_cube>
@rgrinberg: you don't mutate it, but parts might live longer than others
<companion_cube>
(I mean yes, inference mutates stuff, like Drup says)
<d_bot>
<rgrinberg> I could be wrong here, but I still think that handling in AST with say, C++ and smart pointers shouldn't be too much of a challenge.
<olle>
Memory pool, not smart pointers
<Drup>
(in any case, I never understood the hard on for manual memory management. Unless you are doing embedded systems or have real time constraints, there are almost no advantages)
<olle>
Or, just don't collect. Lifetime is whole program lifetime.
<olle>
Drup: Yep, depends on domain.
<olle>
If there exists a domain with 80/20 requirement, as discussed on the forum.
<olle>
Looks like there was a game programmer who would be happy to get rid of C code. :)
<Drup>
(if you want to promote these schemes, talk about resources and concurency, not manual memory management)
<olle>
resources?
<Drup>
(there, the gains are much more significant)
<Drup>
file/database/network handles, etc
<olle>
ah
<olle>
Yes, but that's a solved problem.
<olle>
Runtime with green thread, or generators with yield.
<d_bot>
<rgrinberg> I think the arguments isn't _for_ manual memory management, but for things other than GC
<Drup>
like Arc, less good GCs ? :D
<olle>
Swift?
<d_bot>
<rgrinberg> @Drup "less good" has been debunked
<d_bot>
<rgrinberg> (with benchmarks against 4.10)
<companion_cube>
@rgrinberg: in rust they seem to use regions… but no deallocate until the whole file is parsed
<d_bot>
<rgrinberg> Yeah, regions are obviously a good tool too.
<companion_cube>
yeah well, the Koka/lean thing also doesn't handle mutation well
<companion_cube>
so it works only for pure languages like koka and lean
<companion_cube>
at least for now.
<olle>
Final solution: Just buy more RAM :)
<Drup>
hmm, that's quite interesting
<companion_cube>
it's really cool, sure
<companion_cube>
but no cycles
<Drup>
that's really not "debunking GCs" though, you need to fundamentally redesign the language, and it's a similar tradeoff than Rust when it comes to convenience/control/safety.
<companion_cube>
^
* olle
GC can't melt steel beems
<companion_cube>
beams*
<d_bot>
<rgrinberg> Sure, but ARC being strictly inferior has mostly been debunked
<olle>
sorry, right, just googled it ^^
<olle>
Arc is better by algorithms getting rid of Arc?
<d_bot>
<EduardoRFS> ```ocaml
<d_bot>
<EduardoRFS> module F (P: sig val id: 'a -> 'a end) = struct
<d_bot>
<EduardoRFS> let v = (P.id 1, P.id "")
<d_bot>
<EduardoRFS> end
<d_bot>
<EduardoRFS>
<d_bot>
<EduardoRFS> let f (id: 'a -> 'a) = (id 1, id "")
<d_bot>
<EduardoRFS> ```
<d_bot>
<EduardoRFS>
<d_bot>
<EduardoRFS> Why does the first example works, but the second doesn't? Aren't they in practice the same from a type point of view? And why making the record trick to transform into an existential type makes it work?
<companion_cube>
this is not really Arc anymore
<companion_cube>
it wouldn't work for Swift, for example
<d_bot>
<froyo> "ocaml type variables are by default unification variables not quantification variables" i suppose
<d_bot>
<rgrinberg> @companion_cube why not? " We believe our approach can be extended to program- ming languages that support cyclic data structures because it is orthogonal to traditional cycle-handling techniques"
<d_bot>
<EduardoRFS> and yes I have no shame on interrupting the conversation with some random type question
<Drup>
(in any case, my conclusion from this paper and various other approaches is rather than it's possible to use various linearity techniques to get the compilers to optimize tons of allocations, but so far, it's not possible to plug a real GC with that, so it's combined with RC-like things because "bleh, good enough and let's give up on cycles")
<d_bot>
<rgrinberg> @EduardoRFS if you pretend that your functions take the type parameter explicitly, it's the difference between `(a : Type) -> a -> a)` and `(a : Type) -> (a -> a)`
<d_bot>
<rgrinberg> in your second example, `id 1` tells the typechecker to substitute `int` for `a`.
<olle>
Drup: Or give up on linked lists xD
<olle>
"they destroy cache locality!"
<Drup>
In any case, I really like their notion of FBIP, that's an interesting notion. The whole thing would probably work quite well in Affe
<d_bot>
<rgrinberg> From all the benchmarks I've seen between OCaml and Swift, I usually notice that Swift does well in imperative, mutation heavy code, but really poorly for traditional FP stuff. I wonder if FBIP could narrow that gap for swift for FP things
<olle>
You also get destructors with rc (if you care about that)
<Drup>
well, Futhark does a very similar optimisation in a similarly typed setting, and is used for computational kernels, so ...
<olle>
So it's not just which one is "better", there are different trade-offs