purr changed the topic of #elliottcable to: a _better_ cult || topics << 'gamedev'
<alexgordon> incomprehensibly: oh and btw, you know those cyclic types I was talking about? turns out ada has them
oldskirt has joined #elliottcable
oldskirt has quit [Ping timeout: 272 seconds]
<incomprehensibly> alexgordon: was never clear on the difference really
<incomprehensibly> alexgordon: i know haskell is nominal? explain structural to me
<incomprehensibly> alexgordon: also explain cyclic types again?
<alexgordon> incomprehensibly: it helps if a language has proper record types, which haskell doesn't
<alexgordon> but anyway
<alexgordon> so say you have
<alexgordon> struct Vec2 { x: float, y: float}, and struct Complex { x: float, y: float }
<alexgordon> in a nominal language these two types are different, one is called Vec2, one is called Complex
<alexgordon> but in a structural language, you could say BOTH are the same type, namely {x: float, y: float}
<alexgordon> this gets more interesting for ADTs. say you have enum Bool { true, false }. you could say the type of that enum is actually {true|false}
<joelteon> so haskell doesn't do that because it uses newtypes for instance selection
<alexgordon> pair that with a swift-like label syntax, and you can just fling .true and .false constructors around however you like
<incomprehensibly> ok so i like some thing about structural
<incomprehensibly> but i feel like identifying Vec2 and Complex is really bad
<alexgordon> yeah the ADT aspect is more compelling to me
<incomprehensibly> like i want some kind of like semantic thing
<incomprehensibly> like, ultimately the meaning of a type is in how it is converted to other types
<incomprehensibly> slash results in output or whatever
<alexgordon> lolol
<purr> lolol
<incomprehensibly> also if everything based on Vec2's default methods vs Compelx methods explores totally separate regions of the space of sequences of bits that the two types comprise
<incomprehensibly> then,
<incomprehensibly> they're just not the same at all
<incomprehensibly> identifying by that they both use float is just bad imo
<alexgordon> well that's the rub
<alexgordon> incomprehensibly: both use float and both have the same field names
<incomprehensibly> so i guess i'm on the nominal side with like, more privileged isomorphism/conversion semantics
<alexgordon> if you changed to Complex { re: float, im: float }
<alexgordon> then it would be different
<incomprehensibly> alexgordon: right but what if you just named complex theta: float, r: float
<incomprehensibly> but like
<alexgordon> incomprehensibly: then it would be different field names, so different
<incomprehensibly> what if the x and y are like, on a different coordinate space
<incomprehensibly> or it's Vec3 and something else with x y z but one is right handed and one is left handed
<joelteon> so...faking nominal types in structural typing?
<incomprehensibly> i don't like idenitifying the field names at all
<alexgordon> incomprehensibly: the main advantage is the universal construction syntax, because then you can just throw { x: 10, y: 20 } around and not give it a name. then any function taking a Vec2 can take it
<incomprehensibly> it's so arbitrary
<joelteon> it's structural types, but they differ in field names?
<alexgordon> joelteon: that's what ocaml does, without field names it would be chaos
<joelteon> so structural typing is where you differentiate types by their names
<alexgordon> like I said it's about construction, not typing per se
<alexgordon> joelteon: you could say it's a spectrum
<alexgordon> on the one hand you have fully nominal languages like java, on the other you have fully structural languages like er forth I guess?
<incomprehensibly> alexgordon: i feel like you don't need to identify complex and vec2 to have nameless constructors like this?
<incomprehensibly> c's pretty structural right
<incomprehensibly> or assembly's like single typed structural
<alexgordon> incomprehensibly: well no but it's more fragile
<alexgordon> you can do it with hindley milner
<alexgordon> and infer a type for the construction expression
<alexgordon> structural typing avoids that and just says "the type of the constructor is {x: float, y: float} without a specific name"
<incomprehensibly> right i feel like it's a very arbitrary level of supported isomorphism
<alexgordon> isJust :: {Just(T) | Nothing} -> Bool
<alexgordon> orrrr
<alexgordon> isJust :: {Just(T)} -> Bool
<alexgordon> isJust .Just(_) = true
<alexgordon> isJust _ = false
<alexgordon> try that in haskell ;)
<incomprehensibly> well like
<incomprehensibly> who's going to name their own constructors Just and Nothing
<incomprehensibly> I feel like it will be useful once in a thousand years
<joelteon> heh
<joelteon> "try that in haskell"
<joelteon> "why"
<alexgordon> joelteon: fanboy less :P
<joelteon> huh
<joelteon> what
<incomprehensibly> i agree haskell's nominal typing can be a little restrictive
<incomprehensibly> but i don't think this gains you any real power
<incomprehensibly> *shruge*
<joelteon> i figured you like structural typing because it sounds like an awful idea to me
<joelteon> also, isJust (Just _) = True is actually fewer characters
<alexgordon> incomprehensibly: structural typing is to nominal typing what type inference is to manifest typing
<incomprehensibly> like
<incomprehensibly> i don't get what it lets you do even
<incomprehensibly> it's like, when a *coincidence* happens
<alexgordon> it lets you write a function like
<incomprehensibly> sometimes it saves you a line of code
<alexgordon> foo x = .rabbit
<alexgordon> or I dunno
<alexgordon> I can't think of a use for it
<alexgordon> it's just a different style
<joelteon> so lens pretty much does structural typing
<joelteon> isJust = has _Just
<joelteon> makeJust = (_Just 3)
<joelteon> oops
<alexgordon> joelteon: depends if you have to define _Just anywhere else
<joelteon> (_Just #)
<alexgordon> the whole point is that you don't have to define your data structures to use them
<joelteon> well it's defined wherever you make lenses for your record types
<joelteon> oh okay
<alexgordon> you just will them into existence
<alexgordon> it's a lot like dynamic typing really
<alexgordon> but statically checked...
<alexgordon> structural typing + type inference would be pretty far on the road to a statically typed ruby
<alexgordon> or JS
<alexgordon> actually it's a LOT like JS isn't it?
<alexgordon> JS has no data declarations
<alexgordon> incomprehensibly: there you go, structural typing = what JS does
<incomprehensibly> well i hate js's data model ;-)
<alexgordon> :D me too
<joelteon> everything is a hash
<incomprehensibly> haha
<joelteon> but the hash accesses are now statically checked
<joelteon> nice
<alexgordon> right
<alexgordon> and it's not a hash but a compact struct
<katlogic> tl;dr: Haskell is a tricky language for smart and tricky people who like to dabble around because type system is tricky and makes them satisfied. Use alternative purely functional programming language such as Node.js for true web scale power in the cloud.
<alexgordon> katlogic: :D
<incomprehensibly> katlogic: :D
<alexgordon> node.js is kinda awesome if you can stand it
<joelteon> so you can't do exhaustive pattern match checks with structural typing
<incomprehensibly> i can't get past the fact that
<alexgordon> joelteon: you can? I think
<incomprehensibly> a simple well known well researched syntactical transformation
<incomprehensibly> (CPS)
<alexgordon> incomprehensibly: god I know
<incomprehensibly> it's SO FUCKING SIMPLE AND OBVIOUS
<incomprehensibly> like that's 99% of what makes paws better than node
<alexgordon> joelteon: it depends on if you declare the type of your function or not
<joelteon> but the whole point of type inference is to make writing code easier
<alexgordon> but who doesn't declare their functions in practice?
<alexgordon> function types
<joelteon> but that's the point
<alexgordon> type inference is great inside a function
<joelteon> the type is inferred to assist the developer
<alexgordon> terrible between top level functions
<joelteon> that's the whole point of it
<joelteon> once your code is done it will have type signatures
<alexgordon> does not the same logic apply to data structures?
<alexgordon> declare them when you're done, but while you're working you might want to skip the declarations
<joelteon> so how does that help exhaustiveness checks in pattern matching during development, if to do it you have to write a function signature
<alexgordon> joelteon: I'm not exactly sure you would always have to write a function signature
<alexgordon> not sure at all
<joelteon> well ok i'm still confused
<joelteon> does structural typing allow sum types
<alexgordon> joelteon: yes
<alexgordon> absolutely
katlogic has quit [Ping timeout: 244 seconds]
katlogic has joined #elliottcable
<incomprehensibly> alexgordon: totally different topic, i have a cool idea for a tiny language for games/audiovisual stuff
<incomprehensibly> the idea is everything is like it's analogue
<incomprehensibly> you draw on the screen via x, y, and brightness signals for what's like a cathode ray tube
<incomprehensibly> like in a 2d oscilloscope or an old arcade game
<alexgordon> incomprehensibly: haha retro
<alexgordon> incomprehensibly: so it would only be grayscale?
oldskirt has joined #elliottcable
<incomprehensibly> alexgordon: yeah so i'm going to make it in browser at first, paste in your little set of equations and it will show up on maybe even a cutesy box with a frame
<incomprehensibly> alexgordon: might have rgb tubes, or color params, or something
<alexgordon> incomprehensibly: also how would refreshing work?
<incomprehensibly> fades away
<alexgordon> ah cool
<joelteon> ok that's not exhaustive though
<joelteon> that's "does this struct contain a .male member?"
<joelteon> maybe is either just or nothing but not both
<alexgordon> joelteon: it's exhaustive in the type that's specified :P
<joelteon> ok but isMale (anything else) is false
<joelteon> how would you model Either?
<joelteon> whereas in Haskell it wouldn't even typecheck if you didn't pass Male or Female
<joelteon> say you pass in Just 3 to isMale
<joelteon> see the thing is, nobody ever uses isJust anyway
<joelteon> people use pattern matching or the stdlib functions that shortcut pattern matching
oldskirt has quit [Ping timeout: 272 seconds]
<alexgordon> joelteon: yeah I guess
<joelteon> say I have a function that takes Left something or Right something
<joelteon> what do I do when the argument passed in has neither member?
<alexgordon> you would probably have to type it as {.male|.female} for stronger type safety
<joelteon> Maybe is kind of okay because in the non-Just case, you can just discard what you're given
<joelteon> which looks like Nothing
<joelteon> but if you expect to be able to use any input you get, I don't understand how it would work
<joelteon> it would be like every sum type has an implicit Nothing member
oldskirt has joined #elliottcable
oldskirt has quit [Ping timeout: 272 seconds]
<alexgordon> incomprehensibly: so I just read this on reddit and it blew my mind
<alexgordon> "You can in GHC using the Generics extension. The basic assumption is that any data type can be turned into a "Generic counterpart" using a sums-of-products representation (basically, tuples and sum types). To do this, there is one special class built into the compiler you derive from, called Generic."
alexgordon has quit [Quit: My iMac has gone to sleep. ZZZzzz…]
oldskirt has joined #elliottcable
oldskirt has quit [Ping timeout: 260 seconds]
alexgordon has joined #elliottcable
katlogic_ has joined #elliottcable
katlogic has quit [Ping timeout: 240 seconds]
katlogic_ has quit [Ping timeout: 245 seconds]
katlogic has joined #elliottcable
oldskirt has joined #elliottcable
oldskirt has quit [Changing host]
oldskirt has joined #elliottcable
oldskirt has quit [Ping timeout: 246 seconds]
<incomprehensibly> alexgordon: ooooooh
<incomprehensibly> alexgordon: knew about generics but didn't know how it workd
oldskirt has joined #elliottcable
oldskirt has quit [Ping timeout: 260 seconds]
alexgordon has quit [Quit: Computer has gone to sleep.]
oldskirt has joined #elliottcable
katlogic_ has joined #elliottcable
katlogic has quit [Read error: Connection reset by peer]
katlogic_ has quit [Ping timeout: 260 seconds]
katlogic has joined #elliottcable
eligrey has quit [Quit: Leaving]
oldskirt_ has joined #elliottcable
oldskirt_ has joined #elliottcable
oldskirt has quit [Ping timeout: 260 seconds]
meowrobot is now known as butts
butts is now known as meowrobot
meowrobot has quit [Quit: let us connect our intestines and mutually digest]
oldskirt_ is now known as oldskirt
oldskirt_ has joined #elliottcable
oldskirt has quit [Ping timeout: 244 seconds]
ELLIOTTCABLE has left #elliottcable [#elliottcable]
meowrobot has joined #elliottcable
meowrobot has quit [Quit: let us connect our intestines and mutually digest]
meowrobot has joined #elliottcable
alexgordon has joined #elliottcable
oldskirt_ has quit [Ping timeout: 260 seconds]
eligrey has joined #elliottcable
oldskirt has joined #elliottcable
<nuck> Okay, so you guys are pretty much the craziest programmers I know. Got any ideas on how to sanely implement a decorator in JS without ES6 proxies?
<nuck> I'm thinking my two options are (a) copy methods onto the instance using a .decorate() method or (b) create a .get() method like Ember.js does
<nuck> Obviously leaning towards A, but it's still kinda shitty
<nuck> I have found like 30 decorator patterns in JS which are awful D:
<oldskirt> why not just set the prototype of the deocrator/proxy to the original object?
katlogic has quit [Read error: Connection reset by peer]
katlogic has joined #elliottcable
oldskirt has quit [Ping timeout: 260 seconds]
oldskirt has joined #elliottcable
oldskirt has quit [Ping timeout: 244 seconds]
<nuck> hmm so basically decorator.prototype = instanceOfObject
<nuck> I hadn't thought of that
<nuck> But it should theoretically work
<nuck> Actually I have no idea. I'm too tired to be programming.
<vigs> that makes three of us
<nuck> Fuck it I'm too lazy to wrangle prototypical inheritance right now. I'm just gonna copy things onto the object
<nuck> omg one of my mom's students is named "admin"
<nuck> That's gonna confuse the shit out of a sysadmin someday
<vigs> LOL
<purr> LOL
<vigs> love it
<alexgordon> man type systems are hard
<alexgordon> scoping is doubly hard
sharkbot has quit [Remote host closed the connection]
sharkbot has joined #elliottcable