<whitequark>
re st2: it's st3 (doesn't matter), and it has my hack for hidpi on linux
<devyn>
ah
<whitequark>
but it has a fixed pixel height hardcoded somewhere
<devyn>
I see
<whitequark>
also you can't really enlarge the sidebar font, which also sucks
<devyn>
well I didn't realize there was an st3
<whitequark>
and selector (Shirt+Ctrl+P, etc)
<whitequark>
all reported to the author but he's kinda lazy
<devyn>
heh
<whitequark>
why did I even bother to buy it
<whitequark>
фдыщ
<devyn>
I'm happy with vim
<whitequark>
also
<whitequark>
<3 ocaml
<purr>
Let it be known that whitequark hearts ocaml.
<devyn>
fduscsh or something
<devyn>
shch
<devyn>
idk
<devyn>
haven't paid much attention to cyrillic
<whitequark>
wrong layout
<devyn>
heh
<devyn>
whitequark: oh yeah, I noticed it was OCaml... never used it myself but it just looks like any other FP-oriented language to me lol
<purr>
lol
<whitequark>
well
<whitequark>
it's "practical"
<whitequark>
which means people actually use it and it allows you to do weird shit if you want
<whitequark>
like bypassing type system
<devyn>
like unsafeCoerce? :)
<whitequark>
I like practical things
<whitequark>
well
<whitequark>
I'll take a second look at haskell when monads will start to compose nicely
<whitequark>
aka, when I will be able to present a pure interface from impure implementation.
<whitequark>
a huge plus of ocaml for me is that it has LLVM bindings
<whitequark>
and those mostly (as I've learned tonight... :/) don't segfault if I misplace a thing somewhere
<whitequark>
LLVM fucking loves to segfault
<whitequark>
look at it the wrong way, boom, you have a coredump
<devyn>
monadic IO is shitty, but presenting a pure interface from an impure implementation in a good™ way means, to me, using contracts of some sort
<whitequark>
elaborate ?
<devyn>
essentially, if you're going to do that, you should have to guarantee to the compiler that your code is safe
<devyn>
a lot of imperative languages hit a bit of a wall with optimization
<devyn>
because they have to assume a lot of things are out of their control
<whitequark>
hm
<devyn>
you can apply a lot of optimizations to pure Haskell code because the compiler knows absolutely everything that can possibly happen with that code
<whitequark>
a lot of languages try to cram insane amounts of invariants in the type system
<whitequark>
I think it's simply a wrong way to do it
<whitequark>
since your type system, no matter how expressive it is, is not absolutely expressive (or otherwise you'd solve the halting problem)
<whitequark>
and in practice, you're bound to have and need an invariant which it cannot express
<whitequark>
the simplest form of it is "a remote service"
<devyn>
and Haskell solves that rather crudely by putting anything that involves IO "outside the box" so to speak
<whitequark>
in Foundry, I use the type system mainly for generic programming--inferencer "fills in the blanks" in the generic code
<whitequark>
and there are some very very very basic invariants which also give disproportionally huge benefits when optimizing
<whitequark>
such as immutable bindings
<whitequark>
optimizers <3 immutable bindings
<devyn>
heh
<whitequark>
I don't really think that stuff like laziness and parallelization should be handled by the compiler in the general case
<whitequark>
since that means that people will have a hard time reasoning about the behavior
<whitequark>
Foundry's optimizer is a) really dumb: it's a partial evaluator which evaluates *all* paths it could, and eta-expands a certain subset of functions
<whitequark>
and b) predictable: you cannot even disable it.
<devyn>
fair enough. I'm not convinced they should be either
<devyn>
not saying Haskell is some kind of godly language, because it isn't; there are many instances in which I just can't use it because it would be so horrible
<devyn>
there are also things it does very well
* whitequark
nods
<whitequark>
OOP in OCaml is unusable
<whitequark>
for example, it cannot type two classes with a parent-child link where the parent creates the child
<whitequark>
the inferencer chokes somehow and I never found a way to fix it, or got anyone to fix it for me
<devyn>
huh
<whitequark>
I blame early binding
<whitequark>
I really don't like how OCaml binds *everything* excessively early
<whitequark>
makes any metaprogramming an incredible PITA
<whitequark>
I mean, I see how it is designed in a consistent way and that way probably even makes sense in theory
<whitequark>
but after ruby, this is goddamn painful
<devyn>
haha, yes, if I have a very general-purpose program that doesn't need to be horribly fast and is fairly non-abstract, you bet I'm going to use Ruby
<whitequark>
Foundry has two phases, so it is not a problem for it... first metaprogramming, then early binding
<whitequark>
also did you read my article?
<whitequark>
on metaprogramming in foundry
<devyn>
I didn't
<devyn>
linky
<whitequark>
it's fairly dense so unfortunately most of people I know kind of passed it :/
<whitequark>
didn't regret it even for a second. only a masochist would implement a language in ruby.
<whitequark>
ocaml is not ideally suited for it, but is lightyears ahead ruby
<whitequark>
like it very much.
<devyn>
whitequark: reading through your article
<devyn>
this is very exciting
<devyn>
I love it
<whitequark>
^_^
<devyn>
from the looks of it you've basically made something that feels just like Ruby but compiles to machine code, is statically typed, and is fully transparent to the underlying machine, the latter point being frequently overlooked in new "systems programming" languages
<whitequark>
yes
<whitequark>
there are a few incorrect stances in it due to various modifications I added since I originally wrote it
<whitequark>
for example Foundry will support true polytypes
<whitequark>
that's required for proper region inference
<whitequark>
generally, this does not work well if I want precise garbage collection, so it's probably not worth it to support polytypes generally
<whitequark>
should investigate that though
<devyn>
this looks really great
<devyn>
finished reading btw
<devyn>
whitequark: how's C interop right now?
<whitequark>
right at this moment the compiler I have at hand doesn't have it :) but for that matter it's very much WIP so I'll explain how its basics combine
<whitequark>
so. I have a set of basic types, e.g. parametric width integers and tuples, which map directly to LLVM types
<whitequark>
so if you need simple C interop, you do smth like "def self.c_method(x, y) : (Unsigned(32), Unsigned(32)) -> Signed(16) = external "c_method"
<whitequark>
that however doesn't deal with memory lifetime
<whitequark>
so, since regions allow me to do it very cleanly, I add a *limited* form of RAII, just to manage the memory allocated inside C code
<whitequark>
so if you have foo_create, foo_perform and foo_finalize, that'd be a class with def initialize, def perform and def finalize
<whitequark>
which map to the C operations and integrate with object lifecycle in Foundry
<whitequark>
you could also tweak the regions with the standard language tools, e.g. if your foo_create allocates shit at heap, you explicitly stuff the outermost region in the class you define
<whitequark>
and if foo_create initializes a memory region you provide for it, well, you can also express that
<devyn>
hm
<devyn>
okay
<whitequark>
if you want to call Foundry from C, well, you can also do that--Foundry will create a function for every method you export, and decent LTO will get rid of call penalty for field access
<whitequark>
if you want to *allocate* Foundry from C, things get tricky
<whitequark>
honestly I've no idea how/if I will provide that
<whitequark>
most likely you'll have to write some shims yoursel.f
<devyn>
fair enough
<devyn>
well Foundry sounds really great to me
<whitequark>
cool
<whitequark>
working really hard right now to get it in shape
<whitequark>
I have some demo boards already, and everything should be good for a small demo on 27th Sep
<devyn>
when you do I'd be willing to help with stdlib I guess
<whitequark>
oh that's really nice
<whitequark>
you'll get a free demo board :)
<devyn>
:)
<whitequark>
but first I need to figure out why they literally explode
<devyn>
what do you mean by demo board lol
<purr>
lol
<whitequark>
well
<whitequark>
it's a PCB with an STM32 ARM chip on it, a small monochrome display, several buttons and a buzzer
<whitequark>
like a very very old handhend game console, sorta
<devyn>
and you wanna run foundry on it?
<whitequark>
yep
<devyn>
sweeeet
<devyn>
dude that's awesome
<whitequark>
20k of RAM
<whitequark>
that's like a boatload
<devyn>
yeah you can do a lot with 20k when the architecture doesn't make things gigantic :)
<whitequark>
yeah
<whitequark>
and Foundry really shines when you have similar interfaces (eg SPI I2C) but very different underlying hardware.
<whitequark>
heck, you can properly work with registers
<whitequark>
RCC.cr.set(hsien: true)
<devyn>
wow
<whitequark>
which translates to an RMW cycle
<whitequark>
with proper atomic access and alignment
jesusabdullah has quit [Ping timeout: 260 seconds]
jesusabdullah has joined #elliottcable
<whitequark>
and the register definitions are plain Foundry code in headers, in the ruby dsl style :)
<devyn>
you are a god o/
<whitequark>
register :cr, 0x100 do field :hsien, :bool, 1 end
<whitequark>
like this.
<whitequark>
lol
<purr>
lol
<whitequark>
i just wrote a partial evaluator
<whitequark>
dunno why it never occured to anyone else before
<devyn>
lol
<devyn>
so, I realize regexen probably aren't a core feature of the language (lol), but is there any way we can get something nicer than new Regexp("this.is.a.regex.string") grossness?
<whitequark>
sorta
<whitequark>
I actually need it very much, because embedded's kind of centered around various efficient FSMs
<whitequark>
and most of them are regexps essentially
<whitequark>
so
<whitequark>
you might've seen a section on language composition in the article
<whitequark>
what I want is to have a "quasiquotation for languages"
<whitequark>
so that I could for example write a "ragel literal", then interpolate my Foundry code back inside this literal
<whitequark>
my idea of how to implement that is twofold
<whitequark>
first, restrict the interface, both inwards ("interpolation") and outwards ("value") to procedures
<devyn>
oh that's a nice way to do it
<whitequark>
i.e. a "language literal" returns a closure, and its interpolations also appear as closures.
<whitequark>
then, in your host language you probably want pattern matching or at least nice structure decomposition
<whitequark>
(record)
<whitequark>
so for example you could do smth like: %bison{ lp=lparen xs=args rp=rparen #{ (lp:, xs:, rp:) { ... } } }
<whitequark>
here I am using the Foundry keyword argument syntax
<whitequark>
it's not as beautiful as e.g. parser combinators, or PEG combinators, or that funky thing Alan Kay does
<whitequark>
but it's like 1000 times simpler
<whitequark>
and you could retrofit existing LR parsers to work with this.
<whitequark>
(incidentally, implementing an FSM engine in Foundry will also make it optimize really, really well. and all you need to do is to make a bunch of closures.)
<whitequark>
the best part about it is that you don't even need to parse the literal yourself
<whitequark>
you can offload to existing tooling.
<whitequark>
just need to generate some shims, which you can do, because, duh, metaprogramming!
<whitequark>
the %bison thingy is simply a piece of syntactic sugar for passing the very simple (two node types) AST to a certain function