<aantron>
but otherwise if you dont want to traverse the same string repeatedly, you may want to write a parser. maybe there are some easy libraries available, but i think a C-oriented channel will help you more
<Guest93336>
They are talking about 12 year old ass
<Guest93336>
So that's why I'm her
<aantron>
fair enough.
<Guest93336>
Go see by yourself
Guest70_ has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
<aantron>
i am satisfied with just your word :)
<aantron>
depending on how complex your search is, you may want to look at flex to generate a scanner
<mspo>
you can also use regex(3)
<Guest93336>
I implemented the K.R's code about the polish inverse multiplication
<Guest93336>
for exemple if input is : 10 20 MUL 6 10 ADD , 10 20 will be put in stack
<Guest93336>
then by MUL we want the result of 10 * 20 in the stack
<aantron>
in this case you only need to look at the prefix, so you should be able to get away with switch statements and moving an index along your string. not necessarily the most elegant approach
<Guest93336>
Do you know the K.R part chapter 4 about RPN ?
<aantron>
no, but RPN is a standard example.. i think even in flex :p
<mspo>
isn't pattern matching really the way to go here? :)
madroach has quit [Ping timeout: 248 seconds]
<aantron>
ok, the RPN example was in the bison manual: https://www.gnu.org/software/bison/manual/bison.html#RPN-Calc but typically you would use flex to provide the tokens to bison. but bison (yacc) is really overkill here, you can just walk along the token stream and manipulate your stack
seangrove has quit [Remote host closed the connection]
<Drup>
for rpn, my first year university student do it with a switch yeah :p
madroach has joined #ocaml
<aantron>
of course, you could switch to ocaml and use ocamllex.... we have to suggest it :)
<pierpa>
what language they use?
<aantron>
pierpa: bison and flex? i think written in C
<pierpa>
no, I was referring to Drup students
<pierpa>
yes, bison and flex are written in C and generate C (unless they have rewritten them recently :)P
<Drup>
pierpa: C, unfortunatly
<pierpa>
aaaargh
<Drup>
indeed.
<pierpa>
poor kids :(
<fds>
Is C the worst language to start with?
<pierpa>
unless you want to start them with perl, yes
<Drup>
In my opinion, it's not a good language to start with.
<aantron>
probably not ..
<mspo>
perl can parse that rpn in a fairly simple one-liner ;)
<fds>
I'm not saying it's the best, but it teaches you that life is hard and computers don't care about your feelings.
<Drup>
I have had people telling me that "C is a rather simple language"
<pierpa>
it is
<pierpa>
only, it's it's difficult to write software with it
<Drup>
and then I am reminded of one student asking me "How do I get the size of the array"
<pierpa>
:)
<fds>
I thought the idea was that it's simple for compiler writers. :-)
<Drup>
:|
<aantron>
:D
<fds>
pierpa: Haha
<mspo>
~35 keywords?
<Drup>
mspo: the syntax is utterly irrelevant.
<mspo>
Drup: so is "simple"
seangrove has joined #ocaml
<Guest93336>
Bison seems not very accesible
<aantron>
dont use bison for RPN :)
<Drup>
Guest93336: You're sure you don't want to use ocaml for it ? :D
damason_afk has quit [Remote host closed the connection]
<aantron>
and yeah in my experience (which was 10 years ago) flex was much easier to use
Haudegen has quit [Ping timeout: 240 seconds]
<aantron>
bison is nice when you have a complex, potentially changing grammar, and dont need excellent error reporting that cares about humans
skeuomorf has quit [Ping timeout: 240 seconds]
<Guest93336>
first time I heard about flex
<pierpa>
it's a Fast LEX
<pierpa>
and lex is a unix tool since the stone age
<mrm>
Indeed, a stone tool from the stone age :-)
<pierpa>
:)
<aantron>
the stone age being the period from the beginning of time on january 1, 1970, to about.. when?
<Guest93336>
I Implented npr with switch
<pierpa>
"Lex, originally written by Mike Lesk and Eric Schmidt[3] and described in 1975", Wikipedia
<aantron>
well, yes
<pierpa>
"Flex was written in C by Vern Paxson around 1987."
<Guest93336>
Drup I'm done with Ocaml
<mrm>
aantron: From 1970 to the beginning of 90s, when much nicer and less painful tools like ANTLR have appeared.
groovy2shoes has joined #ocaml
<Drup>
I always found the name "ANTLR" do be highly misguiding
<Drup>
I mean, it's for LL* !!
<aantron>
going to have to look at ANTRL
<mrm>
:-)
<Guest93336>
Someone speack French her would be more simple ?
<aantron>
ANTLR
<Drup>
aantron: it's the java thing
<Drup>
It's less good than menhir
<aantron>
ok never mind
<Drup>
:D
<aantron>
jk :)
<aantron>
still, at least as history :)
<Drup>
actually, according to wikipedia, the last version doesn't target java anymore, and targets a bunch of other things
<mrm>
aantron: The only implementation of the algorithm is in Java, but it produces code for various target languages.
<aantron>
yes, thank you. saw the wiki page
<Drup>
ah, still java, nevermind
<mrm>
I'm not a fan of ANTLR, by the way. ANTLR is merely bronze age :-)
<Drup>
anyway, yeah, it's filled with details that make sense only for Java, so it's a bit limited
<mrm>
Yet it's a huge improvement over the Bison family of tools in many respects.
<mrm>
It puzzles me that YACC clones (even the better ones, like Menhir) are still so popular among OCaml users.
<Drup>
have you used menhir ?
<Drup>
I find LR parser generator far superior to LL* ones
Guest93336 has quit [Quit: Page closed]
<mrm>
Drup: Yes, I used it for a couple of projects about 4 years ago. It was much-much better than ocamlyacc, no doubt about that.
<Drup>
I would assume the difference between ANTLR and yacc is one of language and ease of use, not one of underlying parsing technique
<mrm>
Still, it was a huge pain to use because it was difficult to fit the grammar into LR(1), and the grammar analysis error messages (including shift/reduce conflicts) were extremely unhelpful.
<mrm>
Also, it turned almost impossible to make the resulting parser produce meaningful user messages.
<Drup>
Ah yeah, that should be much much better now. But I don't remember all that being any good with ANTLR
struktured has joined #ocaml
Haudegen has joined #ocaml
<mrm>
Drup: Parsing technique is important. I find it that topdown algorithms are much easier to understand and reason about than LR ones. For example, it is much easier to implement decent error handling in ANTLR because of its top-down nature.
<mrm>
Drup: Thank you! I'm not very informed about the latest improvements in Menhir. Perhaps it's much better now.
<mrm>
I also used ELSA when I had to parse C++.
<mrm>
God, that was a nightmare.
<Drup>
(This is very recent work, so it's all new shiny)
<Drup>
(It's in the last menhir version)
<mrm>
That GLR algorithms requires the user to provide custom procedures that are used to resolve ambiguities. Had to write lots of them, and it was extremely difficult to debug.
<mrm>
*algorithm
<Drup>
I don't know GLR parsers much
<Drup>
(a part that I know many dypgen fanatics)
jeffmo has quit [Quit: jeffmo]
<mrm>
GLR is very simple conceptually -- in a nutshell, it's a parser that produces a forest instead of a single tree, and then lets you choose a single tree using some custom procedure. Seems to be a useful approach for such crazy grammars as the one of C++.
<Drup>
I meant that I don't know the tools ;)
<def`>
making heavy use of menhir:
<def`>
- grammar error messages are ok, if your language is lr-1 I would choose menhir over other tech
<mrm>
def`: My languages do rarely fit into LR(1), because they typically are a composition of several existing languages.
<def`>
- can produce good syntax error messages, with initial setup cost
<def`>
(but competitive with other techs?!)
<mrm>
That's why I almost exclusively switched to top-down scannerless parsing, despite certain disadvantages of this approach (mainly, performance).
<def`>
- can parse broken inputs, really nicely :)
<def`>
- I would like GLR im the backend, Indo some autpmated rewriting of the grammar
<def`>
(phone sorry)
<mrm>
Parsing broken input is really useful for an IDE backend. My parser does not support this feature at the moment, sadly.
<def`>
mrm: makes sense, LR1 is good for statis grammars
<mrm>
def`: I used Menhir for parsing several MLOCs of legacy Delphi code, and it was a great fit for an LR tool, because of the blazing fast performance.
<mrm>
My current top-down tool would produce a much slower parser -- perhaps, an order of magnitude slower.
<ely-se>
I can't see anymore inference rules today. :(
<ely-se>
I've had an overdose.
<Drup>
def`: are we going to get the fancy error thingy with the code backend ?
<nullcatxxx_>
fancy error thingy!
jeffmo has joined #ocaml
kakadu has quit [Remote host closed the connection]
FreeBirdLjj has joined #ocaml
govg has joined #ocaml
seangrove has quit [Ping timeout: 265 seconds]
seangrove has joined #ocaml
struktured has quit [Ping timeout: 250 seconds]
AltGr has joined #ocaml
groovy2shoes has quit [Quit: Leaving]
teknozulu has joined #ocaml
struktured has joined #ocaml
ely-se has quit [Quit: Leaving...]
<seangrove>
def`: Did you say that menhir can handle broken inputs nicely and produce good error messages both for users and other programs?
virtualeyes has quit [Ping timeout: 240 seconds]
<def`>
mrm: are you still there? I am very interested in a delphi parser
<def`>
seangrove: experimental versions can do, yes?
<mrm>
def`: Yes, I'm here. What do you want to know?
<def`>
If by luck you have the delphi grammar available somewhere
<mrm>
def`: I don't think I can share the exact Menhir grammar (because it's a part of a proprietary codebase and contains language extensions), but I could give you the grammar descriptions that I gathered on the Internet and used as the basic source of knowledge about the syntax of Delphi.
<mrm>
There is no official syntax specification, unfortunately.
<mrm>
And some of the legacy features are not even mentioned in the docs.
<def`>
mrm: Ok, I will be glad with that :)
<mrm>
def`: One moment, let me search through my archives. Give me your email.
seangrove has quit [Remote host closed the connection]
seangrove has joined #ocaml
struktured has quit [Ping timeout: 240 seconds]
<mrm>
def`: By the way, for a different project (a source transformation and language extension system) I had to reimplement that Delphi parser using a top-down algorithm, because I needed to extend the language in such a way that it no longer fit in LR(1) and required some ugly lexer hacks. Implementing support for quasi-quotation turned out specifically difficult, because in my system those quotes and antiquotes can be used in place of any parsing
seangrove has quit [Ping timeout: 240 seconds]
<def`>
mrm: interesting.
xyh has joined #ocaml
<def`>
It could be possible to extend LR(1) for composing parsers
xyh has left #ocaml [#ocaml]
<mrm>
It's a throwaway program. I wrote lots of such programs, often copy-pasting stuff between them. OCaml is great for quick and dirty hack'n'slash transformation tasks, thanks to the relatively expressive type system.
<mrm>
If only there was a decent syntax extension facility...
pierpa has quit [Ping timeout: 240 seconds]
<def`>
mrm: got it, thanks
<mrm>
def`: I sent you my collection of Delphi grammars. This is all I found on the Internet, and it helped me greatly with figuring out certain details. By the way, all of these grammars are broken in different ways.
<mrm>
If I remember correctly, two of them correspond to Delphi7, and another two are grammars for Delphi 2010.
<mrm>
I don't envy you for having to deal with Delphi ;-)
<def`>
mrm: I am interested in Lazarus compatible software (Last Delphi software I wrote was... 8 years ago I think :))
<def`>
So nowadays it is just out of curiosity, I don't have to work with that anymore.
<def`>
But I would like to automatically extract some knowledge (relation between classes, dependencies between file, ...).
<mrm>
def`: Well, you should be very happy for that :-) I am a very experienced Delphi developer who has to deal with legacy codebases on a daily basis. And I hate Delphi -- it is a tool with a lot of bad smells and a horrible culture around it.
<mrm>
I hate that it's buggy and proprietary and tied to Windows...
<def`>
I still miss the VCL :)
<mrm>
Switching to OCaml from time to time is a refreshing experience.
<def`>
Plus the object system was decent compared to c++ or java
<mrm>
Yeah, VCL is a very nicely designed framework. At least in comparison to MFC and other totally creepy APIs from Microsoft.
<def`>
(that is, it is very close to java without needing strong support from runtime)
<mrm>
It bugs me that there is no garbage collection in Delphi (apart from the slow and buggy reference counting facility).
<mrm>
There also is no decent profiler and no tool similar to Valgrind.
<mrm>
However, I'd still much prefer writing software in Delphi than doing so in plain C :-)
<def`>
So it is not all that bad. I agree for the proprietary culture... Interestingly lazarus did a good job here
<mrm>
At least it has a module system (however simplistic it is).
<def`>
I am impressed by how portable they managed to get "VCL"-like stuff
<def`>
For garbage collection: reference counting is about as devent GC you can get without imposing constraints on the runtime (it is very local logic...)
<def`>
But it is rather trivial to get right, ARC is a joke "yes that's obvious, so what?!"
<mrm>
I recently tried porting a small tool from Delphi7 to Lazarus, and immediately stumbled upon certain fishy situations that I'm not sure how to resolve. For example, in Lazarus (FreePascal), if you send a pointer to a local function into another function, then Lazarus assumes that this local function recieves the environment as the first argument.
<def`>
hmm, that's fishy indeed
<mrm>
def`: Unfortunately, the overloadable reference counting facility (that is accessable through "interfaces") is not very trivial to use. Sometimes I have to manually adjust the reference counter (e.g. setting it to zero in order to avoid a leak).
<mrm>
Also, it's dog slow. Much slower than smart-pointers in C++.
<mrm>
At least in Delphi7.
<def`>
Yes, they wanted to solved the problem, they didn't manage :(
<def`>
I am surprised there are still big codebases in Delphi
<mrm>
The latest versions of Delphi produce much better code (thanks to the LLVM backend) at the expence of extremely slow compilation.
<def`>
Wow delphi used LLVM in the end. That sounds anachronistic to me :)
AltGr has left #ocaml [#ocaml]
<mrm>
Well, Delphi was extremely popular in Russia, in 90s, especially in the petroleum industry. We have lots of expensive legacy systems written in it.
<mrm>
Some of those old programs are not even legacy, but still are frontrunners inside their markets.
<mrm>
And many of them are stuck with Delphi7, because Borland broke backward compatibility in the worst possible way.
<nullcatxxx_>
never used Delphi before. either I'm too young or i didn't start programming early enough
<def`>
:), they should switch to OCaml
<def`>
They got a few things right at the beginning, and screw up everything later
<mrm>
def`: Well, I've tried very hard, at the company I work for now, but so far I couldn't even convince anyone that garbage collection is a good thing. The culture of Delphi... it is infuriatingly conservative.
<mrm>
If you think Java is conservative... well, you haven't dealt with die-hard Delphi guys.
ygrek_ has quit [Ping timeout: 245 seconds]
<mrm>
I mean, there are lots of very qualified programmers who happen to use Delphi (because they have to), but there are also _genuine_ Delphi programmers, with decades of experience, who are like... totally immune to the idea that something may be wrong with their favourite tool.
<def`>
Like 99% developers out there with $TOOL
<def`>
Java, C, .. OCaml :P
<mrm>
Well, I'm not really sure about 99%. Just about any decent programmer I know of uses more than a single tool. Some of them even design tools (including languages).
<mrm>
But _genuine_ Delphi programmers... well, that's a very special breed that could only survive in their proprietary walled garden.
lostman_ has joined #ocaml
seangrove has joined #ocaml
<mrm>
There is a pretty complete stack of technologies there, inside that garden.
<mrm>
I even admit that the IDE is among the best I've ever had to use. And, surprise, it's also written in Delphi.
struk|desk|away is now known as struk|desk
<seangrove>
mrm: What garden?
<mrm>
seangrove: The walled garden of proprietary Delphi-specific libraries and tools.
<seangrove>
def`: By experimental stuff, did you mean merr?
<def`>
no
<seangrove>
mrm: Yeah, I have a friend who raves about Delphi stuff back in the day
<mrm>
It is the most proprietary language-related community (among the large ones).
<mrm>
The one most alien to the ideas of free software.
johnelse has joined #ocaml
johnelse is now known as Guest57363
hunteriam has quit [Quit: Connection closed for inactivity]
Guest57363 has quit [Ping timeout: 240 seconds]
cg has joined #ocaml
johnelse_ has joined #ocaml
<seangrove>
What's the idea behind ` ?
<seangrove>
Any simple example to grok it?
<mrm>
The Lazarus guys resemble a tiny island of freedom and hackery -- a cute flower that grew through the asphalt, to the sheer horror of the enterprise crowds :-)
kansi has joined #ocaml
artart78 has quit [Ping timeout: 272 seconds]
<mrm>
seangrove: You mean, the backtick symbol that can be placed before constructor names in OCaml?
<cg>
anyone familiar with this kind of error? Error: The implementation env.ml does not match the interface env.cmi: Values do not match: val create : '_a t is not included in val create : 'a t
<cg>
the implementation is `let create = { parent = None; tbl = Hashtbl.create 32; }`
<cg>
and `type 'a t = { parent : 'a t option; tbl : (Ast.id, 'a) Hashtbl.t; }`
copy` has quit [Quit: Connection closed for inactivity]
<cg>
I'm not sure why this is an implementation/interface error, shouldn't the client be specifying the type of 'a?
<mrm>
cg: Try adding a dummy argument to "create". A unit value will suffice.
<mrm>
let create () = ...
<cg>
perfect, thanks!
antkong has joined #ocaml
<mrm>
cg: I'm way too tired and sleepy right now to explain why that fix was necessary, but this has to do with generalizing type variables.
<Drup>
but sounds like some dependency constraints are wrong
<struk|desk>
in cudf? what do you mean?
<struk|desk>
oh the deb module
<struk|desk>
got it
Guest70_ has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
struk|desk has quit [Quit: Konversation terminated!]
Guest70_ has joined #ocaml
seangrove has joined #ocaml
Guest70_ has quit [Client Quit]
Guest70_ has joined #ocaml
slash^ has joined #ocaml
struk|desk has joined #ocaml
hockpa2e has left #ocaml ["Leaving"]
SkySkimmer has quit [Quit: Leaving]
seangrove has quit [Ping timeout: 265 seconds]
averell has joined #ocaml
mrm has joined #ocaml
Guest86688 has quit [Ping timeout: 260 seconds]
ontologiae has quit [Ping timeout: 250 seconds]
Guest70_ has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
Guest70_ has joined #ocaml
kolko has joined #ocaml
mj12` has quit [Quit: ERC Version 5.3 (IRC client for Emacs)]
mj12` has joined #ocaml
larhat1 has joined #ocaml
silver has joined #ocaml
larhat1 has quit [Client Quit]
larhat1 has joined #ocaml
jeffmo has quit [Quit: jeffmo]
seangrove has joined #ocaml
seangrove has quit [Ping timeout: 245 seconds]
gbarboza has joined #ocaml
seangrove has joined #ocaml
dsheets has quit [Remote host closed the connection]
Guest70_ has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
cyraxjoe has joined #ocaml
cyraxjoe_ has quit [Ping timeout: 245 seconds]
psy_ has joined #ocaml
shinnya has joined #ocaml
Guest70_ has joined #ocaml
Haudegen has quit [Ping timeout: 245 seconds]
rand has joined #ocaml
rand is now known as Guest17849
kakadu has quit [Quit: Page closed]
dwillems has joined #ocaml
<dwillems>
Hi everyone. I use merlin with vim to write ml and mli files. Since some days, vim crashes when opening ml files. It seems that the line 'execute "set rtp+=" . g:opamshare . "/merlin/vim"' in my vimrc is the reason.
Haudegen has joined #ocaml
jwatzman|work has quit [Quit: jwatzman|work]
dwillems has quit [Ping timeout: 250 seconds]
Guest70_ has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
Guest17849 has quit [Quit: Lost terminal]
sfri has quit [Remote host closed the connection]
Guest70_ has joined #ocaml
Guest70_ has quit [Read error: Connection reset by peer]
kakadu has joined #ocaml
gdrooid has joined #ocaml
yegods has joined #ocaml
ollehar has joined #ocaml
kdas_ has joined #ocaml
sfri has joined #ocaml
darkf_ has joined #ocaml
larhat2 has joined #ocaml
thesnowdog4 has joined #ocaml
zoobab_ has joined #ocaml
bitemyap1 has joined #ocaml
jtmcf_ has joined #ocaml
wagle_ has joined #ocaml
companion_square has joined #ocaml
rks`_ has joined #ocaml
Cypi_ has joined #ocaml
jmasseo has joined #ocaml
tokik_ has joined #ocaml
vodkaInferno has joined #ocaml
clockish_ has joined #ocaml
sigjuice_ has joined #ocaml
Ankhers_ has joined #ocaml
skeuomorf has quit [*.net *.split]
darkf has quit [*.net *.split]
kushal has quit [*.net *.split]
eni has quit [*.net *.split]
jtmcf has quit [*.net *.split]
companion_cube has quit [*.net *.split]
clockish has quit [*.net *.split]
jmasseo_ has quit [*.net *.split]
Cypi has quit [*.net *.split]
larhat has quit [*.net *.split]
sigjuice has quit [*.net *.split]
bitemyapp has quit [*.net *.split]
vodkaInf1rno has quit [*.net *.split]
rks` has quit [*.net *.split]
jlouis has quit [*.net *.split]
clockish_ is now known as clockish
jlouis has joined #ocaml
dmiller has joined #ocaml
eni has joined #ocaml
wagle_ is now known as wagle
Ankhers_ is now known as Ankhers
skeuomorf has joined #ocaml
dwillems has joined #ocaml
skeuomorf is now known as Guest91200
struk|desk is now known as struk|desk|away
kdas_ has quit [Ping timeout: 272 seconds]
seangrov` has joined #ocaml
seangrov` has quit [Remote host closed the connection]
seangrove has quit [Quit: ERC (IRC client for Emacs 24.5.1)]
seangrove has joined #ocaml
<seangrove>
Is there a way to destructure a tuple in a function but have access to the whole thing? e.g. (fun (a, b, c) :as d -> (* d is the full tuple here))
kushal has joined #ocaml
kushal has quit [Read error: Connection reset by peer]
dwillems has quit [Quit: Leaving]
<ggole_>
fun (a, b, c as t) -> ...
<seangrove>
ggole_: Awesome, I wasn't *too* far off :)
darkf_ is now known as darkf
ggole_ has quit [Ping timeout: 248 seconds]
gdrooid has quit [Quit: WeeChat 1.1.1]
struk|desk|away is now known as struk|desk
Cypi has joined #ocaml
Stalkr_ has joined #ocaml
ely-se has joined #ocaml
jlouis_ has joined #ocaml
<seangrove>
I'd like to find the index of an element in the list (and some value indicating it's not in the list), and remove it from the list
struk|desk2 has joined #ocaml
<seangrove>
Looking at the type signatures, it looks like there's nothing under List that will tell me the index
<Drup>
It's a 3 line function ;)
<seangrove>
Drup: Yeah, no biggie
<seangrove>
Just thought there might be an e.g. List.index_of, since there's a List.mem
<Drup>
(it's usually named findi)
<seangrove>
Ah, cool
<seangrove>
It was cool to be able to scan the type signatures and know that the function didn't exist
Cypi_ has quit [Ping timeout: 240 seconds]
jlouis has quit [Ping timeout: 240 seconds]
struk|desk has quit [Ping timeout: 240 seconds]
Stalkr has quit [Ping timeout: 240 seconds]
mankyKitty has quit [Ping timeout: 240 seconds]
<foolishmonkey>
seangrove, you can have a look at the file list.mli in your ocaml distribution
<foolishmonkey>
Drup, to be sure to not use foreign code (when we don't want foreign code)
<Drup>
foolishmonkey: you always at least use the GC ;)
<foolishmonkey>
Yes.
<foolishmonkey>
The GC is always there.
<seangrove>
Doing this: `Core.Std.List.sub retract_list 0 (idx - 1) in`, I get a warning/error (turned all the warnings on high to learn) that labels were omitted. But hitting C-c C-t to get the type signature of .sub, I don't see any mention of labels. Is there a convenient way to look them up while I'm on that line of code?
<smondet>
seangrove: did you `merlin-use` (or `:Use`) core?
<seangrove>
smondet: No, I can give that a try. What does that do?
<seangrove>
So I do see: 'a Core.Std.List.t -> pos:int -> len:int -> 'a Core.Std.List.t
<seangrove>
Ahh, ok, so the labels are ~pos and ~len
<smondet>
seangrove: what it does: it tell merlin to look for stuff in a library; you can also pur that in the `.merlin` config file
yawnt has quit [Ping timeout: 240 seconds]
slash^ has quit [Read error: Connection reset by peer]
bitemyap1 is now known as bitemyapp
<seangrove>
smondet: Yup, it's in there, I just misread the type signature that merlin reported
Guest91200 is now known as skeuomorf
skeuomorf has quit [Changing host]
skeuomorf has joined #ocaml
lobo has joined #ocaml
j_king_ is now known as j_king
MercurialAlchemi has quit [Ping timeout: 252 seconds]
ousado has quit [Read error: Connection reset by peer]
Anarchos has joined #ocaml
ousado has joined #ocaml
ollehar has quit [Quit: ollehar]
struk|desk2 is now known as struk|desk|away
lewis1711 has joined #ocaml
regnat has joined #ocaml
Algebr has joined #ocaml
<lewis1711>
any of you guys use explicit type annotations a lot? once a project gets to a certain size I've found they help out a lot. it's nice to tell at a glance the signature of something
<Algebr>
I use mlis for that
<axiles>
exactly
orbifx has joined #ocaml
<lewis1711>
the outward facing stuff in my modules is just the tip of the iceberg though
<aantron>
i often subdivide big modules into internal modules in a single source files, and constrain them by signatures
<aantron>
signatures are nice. they have a different meaning than type annotations, however
<lewis1711>
maybe it's just a personal quirk of mine then. I'm a big fan of having stuff in one place - type declarations at the definition, unit tests in the same file, etc
<foolishmonkey>
lewis1711, what are type annotations? -annot ?
<lewis1711>
foolishmonkey, like "let square (x : int) : int = x * x "
<aantron>
i would like that as well, the problem is that 'a in a signature is a type parameter, whereas 'a in a type annotation might be unified with "int" in your implementation, and become "int"
<foolishmonkey>
lewis1711, with -anot you don't really need them
<foolishmonkey>
s/anot/annot/
<orbifx>
hello O-Cam-lot
<nullcatxxx_>
hello!
<lewis1711>
foolishmonkey, I don't follow. what's -annot?
<aantron>
a compiler option
<foolishmonkey>
it's a compiler flag
<foolishmonkey>
it creates a .annot file near your source file
<foolishmonkey>
and you can query type and location of definition with that
<foolishmonkey>
C-c C-t and C-c C-l in emacs
<foolishmonkey>
really useful
<aantron>
this is with merlin, no?
<foolishmonkey>
default ocaml
<Algebr>
yes merlin
<foolishmonkey>
oups sorry
<lewis1711>
hmm, I'd rather have the types right next to the definition
<aantron>
that doesnt help when viewing code on github for example, though. its still nice to have type declarations easily accessible
<Algebr>
lewis1711: then open up the merlin-buffer and do c-c c-t when going throught the code
<lewis1711>
my solution is a lot simpler than that
<lewis1711>
;)
<foolishmonkey>
type annotation are annoying, because they can change a lot and you have to maintain them
<lewis1711>
yeah
<lewis1711>
I'm not religious about it
<lewis1711>
but if I look at a function and the type is not obvious - it's getting an annotaiton
<lewis1711>
completely different, but why do functions with labelled arguments sometimes not parse without args?
<lewis1711>
like "blah blah |> List.map (fun x -> ...)" won't parse without the ~f
<aantron>
typecheck*
<lewis1711>
well... parse in the way it parses in my head :P
<aantron>
what are you getting? warning 6?
<lewis1711>
utop # [1; 2; 3] |> List.map (fun x -> x * x);;
<lewis1711>
Error: This expression should not be a function, the expected type is 'a list
<Algebr>
that's fine with the std lib
<Algebr>
you must be using core
<lewis1711>
I am! hmmm.
* lewis1711
once again considers dumping core
<Algebr>
so yes, it would probably be List.map ~f:(fun x -> x * *)
<lewis1711>
yeah, constantly have to add stupid little ~f
<Algebr>
to be fair, having labeled args is a good thing, prefer them
<aantron>
not always, labels have to be globally consistent for your functions to remain as composable as without labels
<aantron>
because labels become part of the type
<lewis1711>
oh. I see
kakadu has quit [Remote host closed the connection]
<aantron>
lewis1711: the reason for this is due to how OCaml decides which argument satisfies which parameter
<aantron>
because labeled arguments can be given in "any" (almost) order relative to each other and unlabeled arguments
<aantron>
in this case ocaml decides to match your unlabeled function to the unlabeled list argument, hence the type error
<lewis1711>
the |> messes it up from inferring that it already has a list arg?
<aantron>
in general the unlabeled arguments match the unlabeled parameters left to right, and the labeled arguments separately match the labeled parameters
<aantron>
yes
<aantron>
because it doesnt have a list arg at that point
Simn has quit [Quit: Leaving]
<aantron>
List.map (fun x -> x * x) would be a partially applied function, if it type-checked :) that is then passed to |>
<lewis1711>
ah! right that happens aftwrard
<aantron>
well in principle some crazy type inference algorithm could be written to deal with this, but obviously we dont have such a one
<aantron>
i dont know the details why. maybe it would be slow or undecidable, or difficult to maintain
<aantron>
regarding usage of labels they are nice in some places, perhaps many. obviously good places to use them are functions like val foo : string -> string -> string -> string. which string is what?
<lewis1711>
a sufficiently smart compiler could do a lot ;)
<aantron>
:)
<lewis1711>
aantron, yeah I agree, with stuff like that it's useful. or adding key value pairs because for some reason I can never remember
<lewis1711>
to hashtables
<aantron>
but i think putting them on basic higher-order combinators and in some other places is a bad idea. it forces values that want to be type-compatible to globally have the same label, which is questionable for library compatibility
<aantron>
plus in this specific case, there is one argument that is a function and one thats a list. not sure what is gained by ~f
<aantron>
i have a suspicion core was trying to make code more readable by allowing reordering of ~f, before usage of |> became common. not sure though
orbifx has quit [Ping timeout: 272 seconds]
<regnat>
aantron: I think that's the reason indeed
<lewis1711>
yeah. it's an annoying bit of line noises for the |> chains, but not the end of the world
<regnat>
Because module conventions want the type t to appear first in the arguments of the function, but it's not practical for composability
darkf has quit [Quit: Leaving]
<aantron>
|> is really nice. if only fold_left would take its "value" arguments as a pair, so i wouldnt have to do "foo |> fold_left (fun a v -> .... .... ....) 0 (* who sees the 0? *)"
<lewis1711>
well, ocaml does have a module-like system which take the type as a first argument implicitly ;)
silver has quit [Quit: rakede]
skeuomorf has quit [Quit: WeeChat 1.3]
lewis1711 has quit [Ping timeout: 272 seconds]
<aantron>
lewis1711: regarding type annotations, you have to watch out with polymorphism: "let foo : 'a -> 'a = fun x -> 0" has type "int -> int"
<aantron>
you need to do something like let foo : 'a. 'a -> 'a = fun x -> 0
<aantron>
this is why i prefer signatures even inside .ml files when its time to annotate with types, annoying as that is
lobo has quit [Quit: leaving]
<wolfcore>
aantron: so `'a.` in that example serves as a forall 'a, to force the type of foo to be polymorphic instead of constrained?
<aantron>
wolfcore: yes.
Anarchos has quit [Quit: Vision[0.9.7-H-20140108]: i've been blurred!]
<aantron>
it "means" 'a is a type parameter in the rest of the type (cannot be constrained), instead of a unification variable (to be constrained during type checking, remaining 'a only if not actually constrained by the code)
<aantron>
this was an unpleasant little surprise during learning ocaml, that 'a in a type ascription is a unification variable, and 'a in a signature is a type parameter
<aantron>
although it makes sense from some practical points of view to make this choice
<wolfcore>
aantron: so if you have your signature in the .mli file you wouldn't need to specifiy that?
<aantron>
yes
<wolfcore>
if you have an .mli file, are signatures redundant?
<wolfcore>
I mean annotations
<aantron>
well a signature in ML parlance is the contents of an mli file
<aantron>
they may be redundant depending on what you want to achieve for readability and whether you have unexposed values in the module or not
Stalkr_ has quit [Ping timeout: 245 seconds]
<aantron>
wolfcore: sorry to be more precise a signature is a "module type", which is what the contents of an mli file are :)
<aantron>
another reason to annotate even with an mli file is when you have a composition of complex functions with unclear types, that are proving difficult to maintain. to restrict the propagation of type errors, you may want to put annotations on various functions
<aantron>
because until your .ml file type checks, the compiler wont check it against the mli file
<wolfcore>
aantron: ah, okay, that makes sense; I haven't been writing signatures because I think Merlin doesn't read them? I actually haven't checked....
<wolfcore>
I usually just annotate, but I didn't know there was a difference between annotations and signatures until now
seangrove has quit [Ping timeout: 240 seconds]
<wolfcore>
I thought that the compiler just checked either one, not that it checked .ml annotations and then mli signatures
<wolfcore>
This is good to know
<aantron>
yeah, its not obvious. even though i would have understood it, i didnt run into this distinction until i was messing around with some complex functors and trying to understand which way the type constraint information was flowing and why.. years after i first tried ocaml :p
<aantron>
wolfcore: i try to avoid mli files too, to avoid repetition, but in practice i end up with mli files almost for every ml file. it feels more "sane" to just see type, val, val, val, and not worry about all the helper functions and implementations lurking inside :)
<aantron>
not to mention abstract types
<aantron>
this is probably one of the greatest advantages of using a signature
<wolfcore>
Yeah the mli does feel like an overview, easier to see everything
<wolfcore>
Abstrac types do seem really useful, probably most useful for user-facing libraries but also to protect oneself from misusing a module
<aantron>
yeah, they are indispensable for code bases that get moderately large. they make it much easier to analyze, and refactor, code
seangrove has joined #ocaml
Guest38 has quit [Quit: My Mac has gone to sleep. ZZZzzz…]