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
Captain Foo
May 11, 2004

we vibin'
we slidin'
we breathin'
we dyin'


Took me a second

Adbot
ADBOT LOVES YOU

JawnV6
Jul 4, 2004

So hot ...
are y'all ready

for the revolution

sarehu
Apr 20, 2007

(call/cc call/cc)
Ctrl+F transpiler

Whew.

Workaday Wizard
Oct 23, 2009

by Pragmatica
why not just use rust? :confused:

M31
Jun 12, 2012
i just came upon this article: http://joeduffyblog.com/2016/02/07/the-error-model/
it talks about the error handling in a language that was never released that was used to implement a kernel that was also never released. that kernel being midori.

since the article is very long, have a summary:

checked exceptions.

and somewhat longer:

some things cause 'abandonment': dereference a null pointer, an incorrect cast, out of memory, divide by zero, overflow and a few others. these can never be handled and cause the process to abort immediately. apparently, you could opt out of this if you really needed to.

method definition requires 'throws' if it wants to throw an exception.

code:
// compile error
int foo() {
	throw new FooException();
}

// correct, 'throws' is short for 'throws Exception'
int foo() throws {
	throw new FooException();
}
error handling is explicit on the call site:

code:
// compile error
int x = foo(); 

// rethrown on exception, so would require 'throws' on the current method signature
int x = try foo(); 

// expression evaluated on exception
int x = try foo() else 42;

// diy
Result<int> x = try foo() else catch;

// compile error, FooException is not declared in the method signature (no dynamic type checking)
Result<int> x = try foo() else catch<FooException>; 
you can throw multiple types, but you probably shouldn't:

code:
int foo() throws FooException, BarException { ... }

Result<int> x = try foo() else catch<FooException>;
if (result.IsFailed) {
	// result.Exception is FooException i assume, it doesn't really go into details
}
there is a special AbortException that can not be supressed: if you try to supress it will be automatically rethrown. to make it go away you need to call a Reset method on the exception with the same token that was used to instantiate it.

also, methods could have pre- and postconditions which were always evaluated on runtime unless the compiler could statically assert them:

code:
void addPerson(string name)
	requires !string.IsEmpty(name)
	ensures Total == old(Total) + 1 {
	... 
}
if they failed the process would abort

Xarn
Jun 26, 2015
Not sure I want my kernel aborting when OOM or some internal counter overflows.

Bloody
Mar 3, 2013

JawnV6 posted:

are y'all ready

for the revolution

no

comedyblissoption
Mar 15, 2006

Shinku ABOOKEN posted:

why not just use rust? :confused:

Bloody
Mar 3, 2013

I believe their suggestion is to replace the llvm IL with rust, then to use rust to generate machine code. it is not clear why this is preferable, and is apparently left as an exercise for the reader

triple sulk
Sep 17, 2014



Shinku ABOOKEN posted:

why not just use rust? :confused:

no one gives a poo poo about it except mozilla

comedyblissoption
Mar 15, 2006

rustlang is sometimes presented as low level, but it's basically a "functional" programming language in sheep's clothing that has similar or higher levels of abstraction than Java/C#/C++

rustlang does kind of have two worlds of low level unsafe and higher level safe

JawnV6
Jul 4, 2004

So hot ...
the self-highlighting is my favorite stylistic flourish, especially the one about a "programmable compiler" that sounds suspiciously like LLVM, but the TODO: list is breathtaking

PRO:
1) Bolting types onto languages that don't have it

CON:
1) No actual compiler hook support yet

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
oh good, i hadn't had someone who knows nothing about pl implementation tell me that i'm doing it wrong enough recently

my favorite idea here is that implementing different languages in terms of a common ir obviously means that they just interoperate. like, scala is a jvm language, and it just interoperates with java, right? that didn't require careful language design and a lot of attention to detail, it actually just works out because they both compile to bytecode

ynohtna
Feb 16, 2007

backwoods compatible
Illegal Hen
i'm the footnote that sheepishly admits that rust doesn't have a formal standard for every other language to target

tef
May 30, 2004

-> some l-system crap ->
i d k about rust but i want to poo poo post about the semicolon

so here is a good place as any to complain about rust's trivial design decisions

and argue that the carelessness of the small details implies a carelessness of the big picture

or something


so, rust has a semicolon, a separator, a delimiter, but not a terminator.

foo; and foo are not semantically equivalent

the idea is that in "a; b; c; d" d is the value, but "a;b;c;d;" nothing is the value

the rationale as i hear it, is to avoid having a return statement, or such that "everything is an expression"

so rust could have done a couple of things to handle the conflict between return statements and expressions


a) explicit nil

if you want the last value of an expression to be nothing, you put nothing there (well, something, a nil), rather that taking something away (the semicolon)


b) eh, gently caress it, return is special

put a return statement to return a value, without it, don't return anything. this makes short functions 7 characters longer


c) ok, return is special, but so is not using return

if there is no return statement, the last value is the return value

if there is one, then there is no implicit return statement


d) reify return value and assign it

fn butt_check(lhs: u32, rhs: u32) -> out: bool { out = lhs.rotate(rhs) }


e) rust's magic semicolon

expressions that end in ; have no value


anyway come to your own preference, but e) is at the bottom for me

i've spent a small lifetime with prolog, a language that has lists that end in a full stop. a special case for the last item in a list is pain and suffering

trailing commas are great in data structures, cause less noise in diffs and have been ok.

tef fucked around with this message at 18:15 on Jul 23, 2016

Volte
Oct 4, 2004

woosh woosh

ynohtna posted:

i'm the footnote that sheepishly admits that rust doesn't have a formal standard for every other language to target
make it output the code that makes it work, obviously

tef
May 30, 2004

-> some l-system crap ->

rjmccall posted:

oh good, i hadn't had someone who knows nothing about pl implementation tell me that i'm doing it wrong enough recently

must make a change tbh

quote:

my favorite idea here is that implementing different languages in terms of a common ir obviously means that they just interoperate. like, scala is a jvm language, and it just interoperates with java, right? that didn't require careful language design and a lot of attention to detail, it actually just works out because they both compile to bytecode

i d k my favourite thing is somehow transforming all other code to satisfy rust's borrow checker

tef
May 30, 2004

-> some l-system crap ->
no wait it's when he says c doesn't compile to x86 but rust compiles to llvm

tef
May 30, 2004

-> some l-system crap ->
a brief history of metaprogramming: it is a terrible idea please stop doing it

Vanadium
Jan 8, 2005

rust semicolons have a pretty high stockholm syndrome effectiveness as far as i can tell

the option requiring explicit return doesnt solve the thing where you want to write x = if foo { bar } else { baz }. i think weve talked about this before tho

JawnV6
Jul 4, 2004

So hot ...

tef posted:

foo; and foo are not semantically equivalent

this reminds me of one of the weirdest verilog gotchas. you can begin a variable with a \, which makes it consume "all characters until the next whitespace". so
code:
  reg [7:0] \signalName;
instantiates an 8 bit register named "signalName;" and if that's not immediately caught you'll get errors trying to reference "signalName"

triple sulk
Sep 17, 2014



tef posted:

i d k about rust but i want to poo poo post about the semicolon

so here is a good place as any to complain about rust's trivial design decisions

and argue that the carelessness of the small details implies a carelessness of the big picture

or something


so, rust has a semicolon, a separator, a delimiter, but not a terminator.

foo; and foo are not semantically equivalent

the idea is that in "a; b; c; d" d is the value, but "a;b;c;d;" nothing is the value

the rationale as i hear it, is to avoid having a return statement, or such that "everything is an expression"

so rust could have done a couple of things to handle the conflict between return statements and expressions


a) explicit nil

if you want the last value of an expression to be nothing, you put nothing there (well, something, a nil), rather that taking something away (the semicolon)


b) eh, gently caress it, return is special

put a return statement to return a value, without it, don't return anything. this makes short functions 7 characters longer


c) ok, return is special, but so is not using return

if there is no return statement, the last value is the return value

if there is one, then there is no implicit return statement


d) reify return value and assign it

fn butt_check(lhs: u32, rhs: u32) -> out: bool { out = lhs.rotate(rhs) }


e) rust's magic semicolon

expressions that end in ; have no value


anyway come to your own preference, but e) is at the bottom for me

i've spent a small lifetime with prolog, a language that has lists that end in a full stop. a special case for the last item in a list is pain and suffering

trailing commas are great in data structures, cause less noise in diffs and have been ok.

this is all terrible

triple sulk
Sep 17, 2014



not your opinions but just that rust handles semicolons so comically

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!
also the opinions, reified returns are maybe the worst possible option in the history of coding

but the rust semicolons are pretty bad

Xarn
Jun 26, 2015

Asymmetrikon posted:

also the opinions, reified returns are maybe the worst possible option in the history of coding

but the rust semicolons are pretty bad

Agreed.

sarehu
Apr 20, 2007

(call/cc call/cc)
Once you decide to have semicolons be an expression separator where everything has to be an expression, you pretty much walk straight into that decision, and it's the best choice under those conditions, because otherwise if/else expressions need explicit nils, or type checking has to get weird. And I heard that making everything be an expression was the right decision, because

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
yeah it seems like an obvious followthrough of the "everything must be an expression" rule, which is not a design decision i agree with

Sapozhnik
Jan 2, 2005

Nap Ghost

tef posted:

trailing commas are great in data structures, cause less noise in diffs and have been ok.

this is the thing that annoys me the most about json, moreso than the lack of (approval for) comments

comedyblissoption
Mar 15, 2006

i like making everything an expression b/c it simplifies reading code in the majority of cases b/c it restricts control flow and what is allowable

this
code:
let x = if some_bool_condition {
    42
} else {
    420
}
is more readable than this:
code:
let mut x = 0; //non-sensical default value
if some_bool_condition {
    x = 42;
} else {
    x = 420;
}
if you didn't have match expressions and if/then expressions and they were more like switch statements and if/then in other langs, you would often have to come up with some non-sensical "default" value, wrap code unnecessarily in functions, or use static analysis to ensure that your variable is assigned on all paths

making everything an expression also results in more consistent, shorter syntax for stuff like lambda expressions instead of having a bunch of special casing in your language

this:
code:
xs.map(|x| x + 1)
is more readable than this:
code:
xs.map(|x| { return x + 1 })

comedyblissoption
Mar 15, 2006

also rust's semicolon thing is similar to using progn in lisps to sequentially chain expressions together to form a larger expression

given this context, rust's semicolon is very consistent and not some random arcane thing with wierd rules

gonadic io
Feb 16, 2011

>>=

comedyblissoption posted:

i like making everything an expression b/c it simplifies reading code in the majority of cases b/c it restricts control flow and what is allowable

this
code:
let x = if some_bool_condition {
    42
} else {
    420
}
is more readable than this:
code:
let mut x = 0; //non-sensical default value
if some_bool_condition {
    x = 42;
} else {
    x = 420;
}
if you didn't have match expressions and if/then expressions and they were more like switch statements and if/then in other langs, you would often have to come up with some non-sensical "default" value, wrap code unnecessarily in functions, or use static analysis to ensure that your variable is assigned on all paths

making everything an expression also results in more consistent, shorter syntax for stuff like lambda expressions instead of having a bunch of special casing in your language

this:
code:
xs.map(|x| x + 1)
is more readable than this:
code:
xs.map(|x| { return x + 1 })

Plus there's the question of return's scope when it's in lambdas or loops or whatever

comedyblissoption
Mar 15, 2006

making everything an expression also makes it easier to idiomatically work with immutable/const values

Weekend Bridges
Apr 8, 2015

by Smythe

comedyblissoption posted:

also rust's semicolon thing is similar to using progn in lisps to sequentially chain expressions together to form a larger expression

given this context, rust's semicolon is very consistent and not some random arcane thing with wierd rules

huh ?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

comedyblissoption posted:

making everything an expression also makes it easier to idiomatically work with immutable/const values

no it doesn't

here's how you idiomatically work with immutable values: you do everything you would normally do, except without trying to mutate them

comedyblissoption
Mar 15, 2006

in list, an expression invoking a function is written with the following syntax:
code:
(function arg1 arg2 arg3)
to sequentially chain expressions together, you can use progn which is a special form (not really a function) which takes multiple expressions and sequentially chains them together:

code:
(progn
    (foo1 arg)
    (foo2 arg)
    (foo3 arg))
rust semicolons are a similar construct for chaining expressions together

Weekend Bridges
Apr 8, 2015

by Smythe
the rust semicolon thing i thought is that rust a; b; c is lisp (progn a b c) and rust a; b; c; is lisp (progn a b c (values))

comedyblissoption
Mar 15, 2006

rjmccall posted:

no it doesn't

here's how you idiomatically work with immutable values: you do everything you would normally do, except without trying to mutate them
a switch/match (or if/else) evaluating to a const value is unnecessarily verbose and harder to read if the switch/match doesn't evaluate to an expression

w/o these constructs evaluating to expressions you must take one of the following approaches:
  • set up an intermediary mutable value w/ a non-sensical default assigned to it and run the danger that not all code paths were assigned
    code:
    int intermediary_mutable_x = 0; //assign non-sensical default
    if (some_bool) {
        intermediary_mutable_x = 42;
    } else {
        intermediary_mutable_x = 420;
    }
    const int x = intermediary_mutable_x;
    
  • have the compiler guarantee that your declared variable is assigned to and doesn't automatically generate a default value for you. you have the potential disadvantage of needing to declare a type to help the compiler out. so something like the following pseudocode:
    code:
    const int x;
    if (some_bool) {
        x = 42;
    }
    else {
        x = 420;
    }
    
  • wrap it in a function
    code:
    const int x = GetValue(some_bool);
    
    fn GetValue(some_bool: bool) -> int {
        if (some_bool) {
            return 42;
        } else {
            return 420;
        }
    }
    

all of the above approaches are more verbose and harder to read than compared to an expression based approach

is there another approach that I am missing?

these issues may partly be the reason why a lot of langs have the ternary expression

VikingofRock
Aug 24, 2008




tef posted:

i d k about rust but i want to poo poo post about the semicolon

Who cares, you get used to it pretty quick and the compiler yells at you if you mess it up. It's not like this is JavaScript's semicolons or something.

tef
May 30, 2004

-> some l-system crap ->

rjmccall posted:

no it doesn't

here's how you idiomatically work with immutable values: you do everything you would normally do, except without trying to mutate them

:swoon:

Adbot
ADBOT LOVES YOU

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder

rjmccall posted:

no it doesn't

here's how you idiomatically work with immutable values: you do everything you would normally do, except without trying to mutate them

is that really true? don't languages like haskell just present you with an immutable interface for data but under the hood much of it is mutated anyhow because otherwise it would be super slow?

asking for amfriend

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