ELLIOTTCABLE changed the topic of #elliottcable to: a _better_ cult || topics += 'gamedev'
<alexgordon>
lol now it can't parse my json, even though python can
<purr>
lol
<alexgordon>
if I have to write one more .as_slice() or .unwrap() I'm going to kill something
<alexgordon>
work it out yourself, you silly compiler
<alexgordon>
rust's use of both ; and EOL would seem to be the worst of both worlds
<alexgordon>
I can get into the habit of always using ; in C
<alexgordon>
I can get into the habit of never using it in python
<alexgordon>
but the last thing I want to do is _think_ about it
<alexgordon>
ugh rust has no decimal type
<alexgordon>
WHYYYYY
<devyn>
alexgordon: it has several decimal types, but literals have to be typed unless inference can figure it out. for example, 3.2f64, or let n: f64 = 3.2
<alexgordon>
f64 isn't decimal
<alexgordon>
it's floating point
<devyn>
oh, then what are you looking for
<alexgordon>
something like python's Decimal
<alexgordon>
base-10
<alexgordon>
arbitrary precision
<alexgordon>
e.g.
<alexgordon>
Decimal("10.1") ** 100
<alexgordon>
will give you whatever 10.1 ** 100 is :P
<devyn>
why the hell would you want that
<devyn>
lol
<purr>
lol
<alexgordon>
devyn: finance
<alexgordon>
can't use floating point for money
<devyn>
just use fixed point for money
<alexgordon>
can't be bothered
<alexgordon>
decimal is better
<devyn>
Rust isn't exactly the kind of language you'd expect to offer something like that in the stdlib
<alexgordon>
yes it is
<alexgordon>
it's a pretty standard thing
<devyn>
I haven't ever heard of it before
<alexgordon>
java has it, ruby has it, python has it, even objc has it
<devyn>
which probably means they're taking it out before 1.0
<devyn>
alexgordon: as for .unwrap() hell, I agree it's a bit ridiculous, but the try!() macro at least helps you handle that properly instead of just saying 'crash on any errors'
<alexgordon>
devyn: for what I'm writing, "crash on any errors" is exactly what I want
<alexgordon>
it's just a CLI tool for personal use, if there's an error I'll fix it :P
<devyn>
fair enough
<devyn>
:p
<devyn>
I wrote Paws.rs, and I've found that Rust is actually really really nice once you get some patterns down well
<devyn>
it's less annoying than doing things properly in C++ by a lot
<alexgordon>
well
<devyn>
and the compiler can help you a lot more
<alexgordon>
I prefer C++ as a language
<alexgordon>
but rust has better batteries included
<devyn>
heh
<devyn>
I actually prefer it as a language
<devyn>
by far
<devyn>
ADTs are nice to have
<alexgordon>
expected item, found `;`
<alexgordon>
I AM GOING TO KILL SOMETHING
<devyn>
lol
<purr>
lol
<devyn>
and I really prefer the trait/impl approach to classical OO
<devyn>
Rust is basically Scala as a systems programming language
<devyn>
and I like Scala.
<devyn>
who really needs turing complete templates anyway
<devyn>
oh god I'm in class right now and doing UML kill me please
<devyn>
UML AND JAVA
<joelteon>
have you done soap yet
<devyn>
that probably won't happen in this class
<devyn>
and I've managed to avoid using it at work mostly
<devyn>
I do send a pre-generated envelope to one server sometimes
<devyn>
but fucking soap is just a nightmare
<joelteon>
i have to say it sure is nice being able to automatically generate a compliant client based on a single file
<devyn>
sure, if you have a language that has nice SOAP bindings that do that for you
<devyn>
…but that shouldn't be necessary >e>
<devyn>
>.>*
<joelteon>
yeah i like client libraries better but
<joelteon>
if i had a choice between a wsdl and an undocumented REST API, i think i would prefer the wsdl
<devyn>
I mean, my issue with SOAP is that it's not just *a nice feature* that it supports that
<devyn>
it's pretty much completely necessary
<joelteon>
yeah it makes sense
<joelteon>
but i am working on a project that's basically consuming every internal API we have
<devyn>
I'd prefer a WSDL if I had a tool that could use it
<joelteon>
and for that, wsdls are great
<devyn>
but reading that by hand?
<joelteon>
well yeah
<joelteon>
we're using a nodejs library that generates a client from a wsdl
<joelteon>
:/
<devyn>
that's how it works in most SOAP libs
<devyn>
that's even how it's done on .NET, last I checked
<devyn>
Visual Studio just generates a whole bunch of C# for you
<joelteon>
yep
<joelteon>
that's how to soap
<joelteon>
i'd complain about overhead, but we have to send 3 certificates and a key to most of the endpoints anyway
<joelteon>
so it's not a big deal
<alexgordon>
devyn: I don't like the traits
<alexgordon>
like I was saying, too much abstraction
<alexgordon>
it's like someone who insists on always using big words
<joelteon>
you don't like add hawk polymorphism
<alexgordon>
I just want to deal in the concrete values, not some protocol that has been invented to go in front of it
<joelteon>
use C
<alexgordon>
C is just as bad
<alexgordon>
ugh I'm not smart enough to implement this
<alexgordon>
getttting there
<alexgordon>
this is the ugliest thing I've ever seen
<alexgordon>
but
<alexgordon>
faster than python
<alexgordon>
yay
irclogger_com has quit [Ping timeout: 240 seconds]
eligrey has quit [Quit: Leaving]
irclogger_com has joined #elliottcable
Sorella has quit [Quit: Ex-Chat]
<devyn>
as much as I love Ruby, honestly, I'd much rather have static typing
<devyn>
a sound static type system, even. not willy nilly C/++
<devyn>
I like Rust because it *does* have the strictness of Haskell
<devyn>
that's not a downside in my mind
<devyn>
hell, I use TypeScript even though it's a Microsoft thing because it actually brings some compile-time sanity to JS
jwilkins has quit [Read error: Connection reset by peer]
jwilkins2 has joined #elliottcable
jwilkins2 has quit [Read error: Connection reset by peer]
jwilkins has joined #elliottcable
jwilkins has quit [Read error: Connection reset by peer]
jwilkins2 has joined #elliottcable
jwilkins has joined #elliottcable
jwilkins has quit [Read error: Connection reset by peer]
jwilkins3 has joined #elliottcable
jwilkins2 has quit [Ping timeout: 245 seconds]
jwilkins has joined #elliottcable
jwilkins3 has quit [Ping timeout: 245 seconds]
alexgordon has quit [Quit: My iMac has gone to sleep. ZZZzzz…]
<nuck>
devyn: Ruby with static types? Isn't that basically just Crystal?
<nuck>
Wait I don't recall if that was actually static typed
alexgordon has joined #elliottcable
jwilkins has quit [Read error: Connection reset by peer]
jwilkins2 has joined #elliottcable
alexgordon has quit [Client Quit]
<devyn>
nuck: hadn't seen Crystal, but looks like it's statically typed but with extremely heavy type inference.
<devyn>
nuck: which is alright, but I think it's good to enforce full type definitions on method or function defs
<nuck>
Yeah that's what I gathered too
<nuck>
I would agree with that. I rather like full type definitions
<nuck>
One language's type system that I fell in love with is Vala. The system of "it's not nullable unless you add a question mark to the type" makes my life so much simpler
<nuck>
EXPLICIT nullability
<nuck>
No "oh whoops null pointer exception"
<devyn>
well it serves a practical purpose too, to have them… it's possible with type inference for something to just happen to be valid, so specifying full types occasionally (like at method definitions) makes that way less likely and also makes type inference a bit easier
<nuck>
There are some places where type inference feels like magic, honestly
<devyn>
and plenty of languages have explicit nullables
<nuck>
And by magic I mean dynamic typing
<nuck>
Yeah explicit nullables are in plenty, but not nearly enough
<devyn>
Haskell is one, with its Maybe type
<devyn>
Scala has Option
<devyn>
Rust also has Option
<nuck>
It's a feature that should be in *all* languages
<nuck>
That + contract programming = much more robust code
<devyn>
fun fact: Option<pointer> is compile-time optimized to a single nullable pointer
<devyn>
in Rust
<devyn>
so Some(x) is x, and None is NULL
<nuck>
No idea what that means, I haven't played with rust yet
<nuck>
Haven't had the chance
<nuck>
Too busy working in C
<nuck>
Writing a library to interface with 1password keychains
<joelteon>
what about Some(NULL)?
<nuck>
Which means dealing with OpenSSL's awful C interface ;_;
<devyn>
joelteon: you can't have Some(NULL), because Rust doesn't have null pointers
<nuck>
Fun fact: some of the OpenSSL functions randomly cause segfaults
<joelteon>
what about in unsafe code?
<nuck>
So you have to work around them via weird ways of allocating an input to a BIO
<devyn>
Rust has a totally different pointer type for foreign interfaces / unsafe code: “raw pointers”
<devyn>
which can be unsafely casted to native rust pointers
<joelteon>
ok good
<joelteon>
so if you cast a raw null pointer to a rust pointer and wrap it in Some, is it then None
<devyn>
I should try that, but I would guess that's what would happen
<nuck>
I like the sound of Rust so far... "Some" "None" "Option"
<nuck>
It's almost absurd how non-jargony that sounds
<devyn>
Haskell's Maybe is even more casual, heh. “Just”, “Nothing”, “Maybe”
<devyn>
hello = Just "Hello, world" :: Maybe String
<nuck>
How is the rest of Rust in comparison to Haskell? No "interfunctor monadic buttfucks" or?
<devyn>
hello = Nothing :: Maybe String
<joelteon>
yeah, rust is very stupid-people friendly
<devyn>
Rust is an imperative systems programming language like C++, with some more functionally inspired things
<joelteon>
as long as you don't ever try to worry about lifetimes
<devyn>
you will have to worry about lifetimes.
<devyn>
for sure.
<devyn>
that's kind of the point.
<joelteon>
well, rest in peace nuck
<joelteon>
if you can't understand monads you can't understand lifetimes
<vigs>
* rust in peace nuck
<devyn>
seriously, monads are pretty damn simple lol
<purr>
lol
<devyn>
they just have a complex-sounding name
<joelteon>
they have a different meaning in J
<nuck>
My gripes with Haskell stem mostly from the weird-ass syntax, the naming scheme, and the boner for calculus
<devyn>
who gives a fuck about APL or J
<joelteon>
there's no calculus in haskell
<nuck>
Not directly
<devyn>
and the syntax is totally not weird at all
<nuck>
But the community has this enormous fucking boner for calc
<joelteon>
the syntax is so simple it's embarrassing to think it's weird
<devyn>
it makes sense for what it's representing
<devyn>
now APL, that's weird.
<joelteon>
it's "foo = bar" and "foo :: type"
<joelteon>
that's it
<nuck>
Haskell's syntax seems too... jumbled
<nuck>
I guess
<devyn>
nuck: there's no boner for calc at all… nothing is related to calc at all
<joelteon>
are you thinking of category theory?
<nuck>
I have no fucking clue, but it's so math-bonery it's not even funny
<devyn>
lol
<nuck>
And I'm not even remotely good at higher-level math
<devyn>
you don't have to be, because it doesn't even have anything to do with higher-level math
<nuck>
I can handle algebra well enough, but anything beyond Math 90 I go wonk
<devyn>
I'm not either
<nuck>
Every explanation I've gotten has dug into the mathematical theories and proofs underlying everything
<nuck>
Too much theory not enough fucks to give
<devyn>
are you sure they didn't just *look* like mathematical theories? that's kind of the idea of Haskell; instead of telling it what you want to do, you tell it what things are and it figures that out for you
<joelteon>
ok, this function has 9 constraints
<joelteon>
i wonder how i should sort them
<nuck>
devyn: It's possible. But damned if I don't get confused
<joelteon>
probably because mappend is "an associative binary operation"
<nuck>
But anyways, the syntax issue, every operator seems *flat*
<nuck>
Like, it feels like math without brackets
<nuck>
Just a soup
<joelteon>
I read that and I was like, "what does it do?"
<joelteon>
that's up to you, it's just an associative binary operation
<devyn>
Haskell's got lots of parens
<joelteon>
if you can define an append and a zero you have a monoid
<nuck>
It does, but somehow it just looks *soupy* to me
<nuck>
I don't know why, but I'm just incapable of reading it no matter how many times I try to learn me a haskell
<devyn>
it helps a lot if you understand what function composition is
<devyn>
because that's a very common pattern
<nuck>
That could be part of why I don't get it. I understand feeding functions and shuffling functions but to me a function is a bunch of code which returns ;)
<devyn>
nuck: if I have two functions: function f(x) { return x + 2; }; function g(y) { return y * 3; }
<nuck>
I've been programming way longer than I've been capable of studying programming theory, so my understanding of things like functions and routines still kind of dates back to BASIC
<devyn>
which in Haskell is: f x = x + 2; g y = y * 3
<joelteon>
f = (+ 2); g = (* 3)
<devyn>
joelteon: shhh, don't confuse him
<joelteon>
f = flip (+) 2
<devyn>
shut up
<nuck>
Actually... joelteon's looks nicer and makes more sense to me
<nuck>
:p
<devyn>
not that that's even necessary
<devyn>
lol
<purr>
lol
<joelteon>
it's ok, addition and multiplication commute
<devyn>
anyway, yes, you can do those too
<devyn>
lol
<nuck>
The lack of anything delimiting the arguments is. I think, part of the soupiness
<devyn>
ah, well that's because functions in haskell only take one argument and only produce one value
<devyn>
that may seem weird to you
<devyn>
but what happens, actually
<devyn>
is that functions that take multiple args
<devyn>
just return more functions
<nuck>
Effectively currying?
<devyn>
f x y z = x * y * z
<devyn>
well it is currying
<devyn>
`f 1` is a function
<nuck>
Thought so
<devyn>
`f 1 2` is a function
<devyn>
`f 1 2 3` is an int
<nuck>
Makes sense
<devyn>
anyway, it would be stupid if you had to do f(1)(2)(3)
<nuck>
I still feel like I'm beating my face against the spacebar
<joelteon>
to be fair, haskell is named after haskell curry
<devyn>
so you don't.
<devyn>
^
<joelteon>
"haskell" is a weird fucking name for humans
<joelteon>
doesn't make any sense
<devyn>
and curry?
<devyn>
well, anyway
<nuck>
That lack of anything separating arguments from function is definitely the largest part of the soupiness
<joelteon>
you mean the argument
<devyn>
nuck: composition basically: let's say I define a new function h(z) { return f(g(z)); }
<nuck>
I'm very picky about my syntaxes
<joelteon>
there's only the one
<devyn>
nuck: in Haskell I could just say: h = f . g
<nuck>
haha yeah
<nuck>
mmm the dot operator
<devyn>
nuck: but anyway, all of these things are what makes Haskell read so differently :p
<devyn>
it actually ends up being nicer if the code is well written and you're used to it
<devyn>
way, way nicer IMO
<nuck>
And it's still too much whitespace and not enough syntax for me :p
<nuck>
But that's okay. I'm a really picky bastard
<devyn>
well Haskell's syntax is effectively two dimensional, anyway
<nuck>
I still haven't learned Go because the syntax frustrates me
<devyn>
it determines how things go together based on how you align them
<nuck>
I love the language concept, hate the syntax
<nuck>
Same gripe I've got against TypeScript
<devyn>
but TypeScript is just like, Java/C#
<devyn>
syntax
<devyn>
with pascal-order types
<joelteon>
go sucks
<devyn>
lol
<purr>
lol
<joelteon>
and will never not suck
<nuck>
Whichever one of the ocmpile-to-JS languages did the odd order of variable and type
<nuck>
I can't remember
<nuck>
There's too fuckign many
<devyn>
(x: number) you mean?
<devyn>
yes, TypeScript does that
<nuck>
Yeah
<devyn>
but that's not odd
<devyn>
that's actually very old too
<devyn>
Pascal had that order
<devyn>
C went the other way
<devyn>
I prefer that order honestly
<nuck>
I'm aware it's old, but it comes from the langauge lineage I hate
<nuck>
I have an intense burning hatred of the Pascal lineage
<devyn>
lots of things are part of both lineages :p
<nuck>
They never grasped that wordiness didn't make things better
<devyn>
NUL-terminated strings are generally a pretty bad idea and Pascal used length-specified strings
<devyn>
guess which is more popular now
<nuck>
Hah yeah
<nuck>
I actually implemented a length-specified string for internal to my onepassword lib... because too much binary data
<devyn>
NUL-terminated strings just suck, plain and simple
<nuck>
They really do
<devyn>
they have the potential to cause so many bugs that length specified strings just can't
<nuck>
I'm glad C makes it pretty easy to build length-delimited strings though
<devyn>
yeah but you can't change what the literal syntax generates, though
<nuck>
Then malloc it a giant block and magic mothafuckah
<nuck>
mmm yeah
<nuck>
But a macro can presumably fix that
<devyn>
yes, it can, but it looks ugly… best case is something like S("...")
<nuck>
Not as pretty but I'm sure I can just do OPSTR("Salted__")
<nuck>
Oh god that's gonna be fun to implement
<nuck>
1password stores certain items in this weird form where it has Salted__ at the front of the string and then 8 (I think) bytes of salt
<nuck>
And then uses a weird front-padded scheme to pad
<nuck>
I don't know what the hell they're doing not just using something like PKCS#11 or whatever
<devyn>
potentially because they didn't salt before and now they do
<nuck>
Nah it's always been salted, at least in this form
<devyn>
always is a long time
<nuck>
Not really
<nuck>
AgileKeychain was introduced in 2009
<nuck>
CloudKeychain in 2013
<nuck>
I'm glad they ditched the weird menagerie of plist files, JSON files, and binary files though
<nuck>
This crypto code is basically suffering, but I refuse to give in and let OpenSSL win
<nuck>
I'm too stubborn to give up
<vigs>
TIL the heartbleed thing was basically someone using strcpy instead of memcpy
<vigs>
alt-title: TIL strcpy is a bad, bad idea and shouldn't exist in stdlib
<nuck>
Yeah pretty much, and it's a friendly reminder that crypto code should never ever ever ever ever work with nul-delimited strings
<nuck>
EVER.
<vigs>
oh?
jwilkins2 has quit [Quit: Bye]
<nuck>
strcpy is a fine idea, vigs. It's the whole of string handling in C that is broken
<vigs>
I noticed
jwilkins has joined #elliottcable
<vigs>
strcat is a joke
<vigs>
well, it makes sense, but
<vigs>
n^2 time, apparently
<nuck>
Remember that strcat doesn't mean "string concatenate" but "strangle cats"
<vigs>
I didn't even consider the prior
<nuck>
Wait how is strcat n^2
<vigs>
"Feed me a stray cat"
<nuck>
Like, I can't even fathom how you could make that n^2
<nuck>
m = malloc(strlen(a) + strlen(b)); strcpy(a, m); strcpy(b, m + strlen(a));
<vigs>
I think in scanning for a \0, it iterates through the strings over and over to get n^2
<nuck>
Basically
<vigs>
lemme see if I can find this thing about it
<nuck>
I mean it's not perfect and it's probably hella slow but I don't think I even just managed n^2
<nuck>
Technically I think that's O(n) with a rather high constant
<nuck>
Like O(jesuschrist * n)
<vigs>
hah
<vigs>
I *think* it iterates through the string its building every time it wants to get to the end to append something from the first string
<vigs>
thus quadratic time
<vigs>
lemme double-check that
<nuck>
That would be an incredibly odd thing to do
<nuck>
I can think of a few things you could probably do to speed things up too... allocating a "guess" of what you think the length will be, then reallocating if you turn out wrong... probably still faster than the 5 iterations through the strong I did
<vigs>
ohhh no I got it
<vigs>
one strcat is linear time
<vigs>
multiple strcats make it near-quadratic time
<vigs>
because it's iterating through the now-longer string in order to reach the null
<nuck>
If you keep using strcat over and over, like to build a string, you're definitely doing something wrong
<vigs>
yup
<vigs>
brb
<nuck>
Just sounds like a bad idea because strcat doesn't just modify a string, it *allocates a new one*