Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Vanadium
Jan 8, 2005

i also need a managable project to tackle in rust so i have a more defensible standpoint for all my complaints about it

Adbot
ADBOT LOVES YOU

emoji
Jun 4, 2004

Soricidus posted:

isn't it that thing by the crazy dude who thinks jesus talks to him through his rng

You're thinking of the other insane OS person. That appears to be the work of the urbit/nock/hoon guy

Zaxxon
Feb 14, 2004

Wir Tanzen Mekanik

Soricidus posted:

isn't it that thing by the crazy dude who thinks jesus talks to him through his rng

no I think it's the crazy dude who gave himself a harry potter name and wants to bring back monarchy.

fritz
Jul 26, 2003

mencius moldbug

Soricidus
Oct 21, 2010
freedom-hating statist shill

kraftwerk singles posted:

You're thinking of the other insane OS person. That appears to be the work of the urbit/nock/hoon guy
gently caress, for some reason I thought they were the same person

my shame shall live forever

Notorious b.s.d.
Jan 25, 2003

by Reene

kraftwerk singles posted:

You're thinking of the other insane OS person. That appears to be the work of the urbit/nock/hoon guy

Zaxxon posted:

no I think it's the crazy dude who gave himself a harry potter name and wants to bring back monarchy.

these two, however, are the same person

Zaxxon
Feb 14, 2004

Wir Tanzen Mekanik

Notorious b.s.d. posted:

these two, however, are the same person

Lord Broldemort.

Workaday Wizard
Oct 23, 2009

by Pragmatica
hey guys i believe the pos should have a positive influence on the world by posting in the rust forum
http://discuss.rust-lang.org/

featuring forum software by our favorite former poster

abraham linksys
Sep 6, 2010

:darksouls:
discourse is ok; it's literally the only app i've ever used that has endless pagination that plays nice with forward/back navigation (tho it's imperfect due to lovely browser scrolling events), and being able to use markdown on a forum is really nice, it turns out

i'm glad more projects are moving off mailing lists, which i've always found unintuitive, difficult to use, and intimidating

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

im the guy intimidated by mailing lists

Jonny 290
May 5, 2005



[ASK] me about OS/2 Warp
Ahh.....Major Domo. We meet again.

*katana unsheathing snick*

Workaday Wizard
Oct 23, 2009

by Pragmatica

fart simpson posted:

im the guy intimidated by mailing lists

you can't post on a mailing list without telling others your email

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Shinku ABOOKEN posted:

you can't post on a mailing list without telling others your email

sounds intimidating

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

JewKiller 3000 posted:

because if you try to extend the hindley-milner type inference algorithm based on unification to solve a set of subtyping inequality constraints then you get an instance of the semi-unification problem which is generally undecidable.

no i don't know what that means. but searches for those terms should bring up some papers written by people who do :)

okay. most type systems can be expressed as a conjunction of relationships between type terms, e.g. "a == b && c == X(b) && a == Int". allowing disjunctions doesn't add any theoretical problems; you just normalize to DNF and solve all the disjoined terms independently. that's inefficient, and it introduces ambiguity questions, but it doesn't change the decidability of the problem. sometimes type systems require checking additional constraints, like type classes in Haskell, but that can often be delayed: you solve the normal type relationships, then check that the types in the solution obey your extra constraints. so basically, most interesting type systems (short of the really advanced stuff) can be expressed as a conjunction of relationships between type terms

in normal system F, the relationships are all equalities, and a type term can be either a variable, a constant (either monomorphic, like "Int", or polymorphic, like "List" or "->"), an application of two type terms ("X Y"), or a type abstraction ("\T:k.X")

if you ignore type abstractions for a second, and your relationships are all equalities, and you disallow infinite types, then you can type-check this with unification. the key is that you have three rules which, together, allow you to immediately eliminate any constraint. (1) if either side of the equation is a variable, you check that the other side doesn't use that variable (if it does, you have an infinite type), and then you just substitute the other side for the variable in all the other constraints. (2) otherwise, if either side is a constant, the other side is required to be the same constant. (3) otherwise, both sides are applications; add constraints that the corresponding parts are equal. rule (3) means you're always working on smaller and smaller terms, except when you apply rule (1), which you can only do a finite number of times (the number of variables you started with; nothing in the solving process creates more variables). so this always terminates, although substitution can make your type terms exponentially large

and this same algorithm works for inferring rank-1 polymorphic types for values: it can be polymorphic over all of the type variables that are still around after the dust settles, essentially adding type abstractions to the (solved + substituted) type of the overall expression. however, this does not lead to a sound execution model for all types in the presence of mutation, hence the polymorphic value restriction (basically, the inferred type must be a function type)

but basically anything you try to do to the type system that can't be done as a post-processing step screws this up horribly

if you try to add type abstractions, unification just totally doesn't work. it's undecidable to reconstruct even interior type information in full system F. applications have to be able to substitute into abstractions, which can create arbitrarily larger type terms; and there are equivalence notions (e.g. "List == ∀T:k.List T") that go off the deep end pretty quickly

if you try to use subtype relationships — really, anything except equality relationships — you run into some interesting problems. rule (2) is straightforward. rule (3) is still feasible, though it now depends on the invariance/covariance/contravariance of the applied constructor, which creates issues with higher-order polymorphism (e.g. the Functor constructor class in Haskell). but rule (1) is a much more difficult problem, because knowing that "v < X" doesn't actually let you eliminate "v". however, it doesn't actually become undecidable, just... difficult. you essentially need a completely separate solving pass for subtyping constraints. polymorphic type inference is still possible, except that solving a constraint system can leave you with not only unbound type variables, but subtype-constrained unbound type variables, which means the type of a value is not always fully expressible in the ordinary type system (e.g. "∀T,T < Cloneable . T -> T"). fwiw, this is essentially swift's type-checking algorithm; we don't allow polymorphic inference

scala's type inference restrictions are unrelated. scala's type-checker is not like hindley-milner, which considers an entire expression at once. scala's type-checker is essentially bottom-up with some contextual propagation: it type-checks sub-expressions separately from their containing expressions, much like java/c/c++/c#, except that it also tries to propagate type context downward when doing so is unambiguous, which it does in two main ways: when initializing a typed variable and when passing an argument to an unambiguous function. the rule about unambiguous functions includes left-to-right propagation, where if Scala can infer a generic type argument from one function argument, it will use that information as part of the type context for checking the next function argument. these rules just aren't generalizable enough to allow parameter inference, and they're pretty limited with return type inference as well

Jonny 290
May 5, 2005



[ASK] me about OS/2 Warp

Shinku ABOOKEN posted:

you can't post on a mailing list without telling others your email

who cares its not 1994 any more stop posting jolly roger cookbook copypasta to GRUNGE-L and you wont get in trouble

Condiv
May 7, 2008

Sorry to undo the effort of paying a domestic abuser $10 to own this poster, but I am going to lose my dang mind if I keep seeing multiple posters who appear to be Baloogan.

With love,
a mod


go is terrible cause it replaces generics with downcasting

cept this guy, looks like he's fixed the lack of generics with function overloading


quote:

In a lot of cases, generics were more trouble than they were worth. In such cases in .NET land, I found that I was often worried about compilation and things like covariant and contravariant relationships to the base type. Then, getting into generics of generics of generics made life really hard, for example: List<Dictionary<string<IEnumerable<HttpRequest>>>>.

the alternative to generics

code:
type Integer16 int16  
type Integer32 int32  
type Calculator interface {  
    Calculate()
}

func (i Integer16) Calculate() { /* behavior here */ }  
func (i Integer32) Calculate() { /* behavior here */ }

func main() {  
    container := []Calculator{Integer16(1),Integer32(2)}
    fmt.Println(container)
}

Condiv fucked around with this message at 08:26 on Oct 15, 2014

sarehu
Apr 20, 2007

(call/cc call/cc)
Julia supports parametric types. I don’t see at the moment why this is relevant. You could achieve similar functionality also with some macrology. Maybe I’m missing something here.

FamDav
Mar 29, 2008

well when you're a blub programmer, its hard to impossible to look up the curve

JewKiller 3000
Nov 28, 2006

by Lowtax

rjmccall posted:

an extremely good post

tyvm for the effort, always good to hear from someone who knows what they're talking about

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I'm too dumb to understand it though.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Suspicious Dish posted:

I'm too dumb to understand it though.

:confused::hf::confused:

Shaggar
Apr 26, 2006
mailing lists are garbage

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I guess it's because every time I read about type systems I learn exactly how much I don't care, and how much I just want to write cool code that does cool poo poo.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
i even tried to make it easier to understand :(

there are two basic type-checking strategies in the world: bottom-up, where you analyze sub-expressions independently of each other, and constraint-based, where you look at an entire expression simultaneously

classic imperative languages tend to be bottom-up. some languages are purely bottom-up, and c is a good example: you can look at any sub-expression knowing only what's currently in scope and tell me what the type is; evaluating that expression will always yield a value of that type, which may then have to undergo type coercion depending on how it's used. so e.g. if you write "float f = someOtherFloat + 5.0;", then "someOtherFloat" is float, "5.0" is a double, "someOtherFloat + 5.0" is a double (requiring the result of "someOtherFloat" to be promoted to double), and that double value gets coerced back to float as part of the assignment to "f"

other languages are predominantly bottom-up with some specific exceptions. java (and i think c#) is purely bottom-up except for method/constructor references ("foo.copy" or "Foo", both without any arguments), which can have an overloaded type that's resolved by looking at the types of the argument expressions; but those are special cases anyway: they're not really standalone expressions, because they're only valid syntactically when immediately called. c++ has similar special cases for overloads, except that c++ sometimes lets you refer to overloaded function names ("foo" or "&foo") and member names ("&Type::foo") as standalone expressions, in which case they have to be resolved contextually; this creates several massive special cases in the C++ type system, but overall it's still mostly bottom-up

scala is an extreme case of hacking contextual typing onto a bottom-up system. think of it as a bottom-up system where the type-checker is given an optional hint of what type it should produce. scala uses these hints for things like closure parameters, so you can write "(a, b) => a > b" instead of "(a:Int, b:Int) => a > b" or whatever, but there are other uses. it can easily fill in hints when there's a cast or an assignment or an initialization of a fully-typed variable. but it also, somewhat heroically, fills in that hint by trying to resolve overloads eagerly, so if you have "foo.bar(x, y)", it will (I believe) check if there's a unique method "bar" taking two arguments, and if so use its parameter types as hints for x and y. and more heroically, it will use information from earlier arguments to pare down the overload set for later arguments; so if there are two methods named "bar", then it will not have a hint for x, but if unhinted type-checking yields a type for x that can only be passed to one of the overloads, then it will have a hint for y. and even more heroically, it will do this for generic methods, so if foo is "foo<T>(List<T>, something)" and x is a List<String> then it knows that T=String when producing a hint for y. it is cool, but there's only so far you can go with hacks like this, which is why some people find scale's type inference really limiting

in contrast, you have the more comprehensive type systems used by sml, ocaml, haskell, rust, swift, and a bunch of others. almost all of these are variants of a type system called "system f", which is extremely powerful but requires you to write complete type annotations basically everywhere. the biggest thing you can do in system f that you can't do in any of these other languages (ignoring language extensions) is arbitrary-rank polymorphism, where you can create and pass around polymorphic functions as first-class values. if you ditch that, you get back the ability to drop type annotations in a lot of places, even in systems that use subtyping

okay i should probably do some actual work today

tef
May 30, 2004

-> some l-system crap ->

rjmccall posted:

i even tried to make it easier to understand :(

i understood it, but i know what unification, and rank polymorphism is.

my translation would be

- types are constraints, and we have a good algorithm for checking these, using equality
- if you do extensions to types after solving these contraints, then it's not so painful
- if you introduce subtyping rules, the number of contraints explode, and pain and suffering

tef
May 30, 2004

-> some l-system crap ->
ps don't most HM systems do type reconstruction a bit, anyway?

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Yeah I still don't manage to actually give a poo poo. I'm going to go write some more code that adds transparency and compositing support to my X server written in JS.

crazypenguin
Mar 9, 2005
nothing witty here, move along

rjmccall posted:

there are two basic type-checking strategies in the world: bottom-up, where you analyze sub-expressions independently of each other, and constraint-based, where you look at an entire expression simultaneously

I'd say bi-directional type checking is another general strategy. On the other hand, I thought Scala was based on bidirectional type checking, and you keep talking about how Scala's a horrible hack. Have they strayed from the original elegance, or do you really not like this approach for some reason?

tef posted:

ps don't most HM systems do type reconstruction a bit, anyway?

I'd guess all do. HM isn't exactly special for any reason other than it hits a sweet spot for doing type inference. Or at least, any reason that I'm aware of.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

tef posted:

ps don't most HM systems do type reconstruction a bit, anyway?

in some sense, you're always doing type reconstruction, because even crazy dependent systems don't require literally every expression to be annotated. the assumption is that putting fully explicit types on all names at their point of declaration and explicitly abstracting and applying generic types is sufficient to make the rest of type reconstruction a trivial bottom-up operation. there are language features (like return-type overloading) that gently caress with that assumption, but only in pretty superficial ways: a pretty-print of a fully reconstructed program needs some way to either explicitly annotate the expected return type, or explicitly identify the intended overload, or else it won't be trivial to fully reconstruct anymore

but yeah, in standard HM the type-checking algorithm is just a layer on top of the type reconstruction algorithm

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

FamDav posted:

well when you're a blub programmer, its hard to impossible to look up the curve

the talent deficit
Dec 20, 2003

self-deprecation is a very british trait, and problems can arise when the british attempt to do so with a foreign culture





this has to end:

code:
TTransport transport = TSSLTransportFactory.getClientSocket("localhost", 9091);
TProtocol protocol = new TBinaryProtocol(transport);
Calculator.Client client = new Calculator.Client(protocol);

client.ping();
int sum = client.add(1,1);

transport.close();
this is perfectly reasonable java code

code:
{ok, TransportFactory} = thrift_socket_transport:new_transport_factory("localhost", 9091),
{ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(TransportFactory),

{ok, C0} = case ProtocolFactory() of
  {ok, Protocol} -> thrift_client:new(Protocol, calculator_thrift);
  {error, Error} -> erlang:error(Error)
end,

{C1, {ok, ok}} = thrift_client:ping(C0),
{C2, {ok, 2}} = thrift_client:call(C1, sum, [1, 1]),

thrift_client:close(C2).
this is absolutely horrible erlang code. it could have been written as:

code:
{ok, Transport} = thrift_socket_transport:new("localhost", 9091),
{ok, Protocol} = thrift_binary_protocol:new(),
{ok, Client} = thrift_client:new(calculator_thrift, Transport, Protocol),

ok = thrift_client:ping(Client),
{ok, 2} = thrift_client:call(Client, sum, [1, 1]),

thrift_client:close(Client)
regretably, way too many programmers are poo poo at interfaces and will gladly copy what someone else did regardless of whether it makes any sense at all

MononcQc
May 29, 2007

the talent deficit posted:

this has to end:


this is perfectly reasonable java code


this is absolutely horrible erlang code. it could have been written as:

regretably, way too many programmers are poo poo at interfaces and will gladly copy what someone else did regardless of whether it makes any sense at all

What's most amazing is that the thrift lib used to be more idiomatic Erlang, and someone decided to go over it and try to program Java in Erlang and this is what you're left with. It's objectively one of the shittiest libraries in the ecosystem.

the talent deficit
Dec 20, 2003

self-deprecation is a very british trait, and problems can arise when the british attempt to do so with a foreign culture





MononcQc posted:

What's most amazing is that the thrift lib used to be more idiomatic Erlang, and someone decided to go over it and try to program Java in Erlang and this is what you're left with. It's objectively one of the shittiest libraries in the ecosystem.

i don't even think it worked for like the last six years. i think i've mostly fixed the code gen and the client. now i'm working on the server

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

MononcQc posted:

Java in Erlang

X language in Y language always produces some amazing poo poo.

MononcQc
May 29, 2007

the talent deficit posted:

i don't even think it worked for like the last six years. i think i've mostly fixed the code gen and the client. now i'm working on the server

A fixed up thrift client would probably be well-appreciated for a bunch of apps here and there, that's pretty cool.

Wheany posted:

X language in Y language always produces some amazing poo poo.

It does. The biggest the mismatch between languages, the worth it is. I'm sure Prolog people have seem some of the nastiest crap in the world.

gonadic io
Feb 16, 2011

>>=

Wheany posted:

X language in Y language always produces some amazing poo poo.

code:
fib (n) = flip evalState (0,1) $ do
{
    forM [0..(n-1)] $ \i -> do
    {
        (a,b) <- get
        put (b,a+b)
    }
    (a,b) <- get
    return a
}

my homie dhall
Dec 9, 2010

honey, oh please, it's just a machine

AlsoD posted:

code:
fib (n) = flip evalState (0,1) $ do
{
    forM [0..(n-1)] $ \i -> do
    {
        (a,b) <- get
        put (b,a+b)
    }
    (a,b) <- get
    return a
}

:eyepop:

FamDav
Mar 29, 2008
hey person who likes rust a lot (vanadium?) is there anything actually explains how modules and crates actually work?

http://doc.rust-lang.org/guide.html#crates-and-modules is a totally useless overview of modules
http://doc.crates.io/guide.html is totally useless for understanding how to have more than two files in a project
https://github.com/rust-lang/rust/wiki/Docs-project-structure is, again, useless

ok, lets look at the cargo code because they dog food this poo poo

https://github.com/rust-lang/cargo/tree/master/src/bin

okay so theres cargo/lib.rs, which was mentioned in the cargo guide, but now each subfolder has a mod.rs? and every other file in that directory corresponds to a module? and i dont have to wrap the contents of those files in mod?

thanks for explaining this to me, rust developers.

FamDav
Mar 29, 2008
its not that this system doesn't make sense and work when you understand it.

its that its literally undocumented: https://www.google.com/search?q=rust+mod.rs&oq=rust+mod.rs&aqs=chrome.0.69i59j69i60l3.989j0j7&sourceid=chrome&es_sm=91&ie=UTF-8

Adbot
ADBOT LOVES YOU

the talent deficit
Dec 20, 2003

self-deprecation is a very british trait, and problems can arise when the british attempt to do so with a foreign culture





http://rustbyexample.com/mod/split.html

does that help?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply