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
sink
Sep 10, 2005

gerby gerb gerb in my mouf

1337JiveTurkey posted:

Optional types feel half-assed when mixed with parametric polymorphism because while Foo[T] and Foo[Option[T]] may look closely related, they're nothing alike. Any situation where a method could return an Option[T], it should be equally valid to return a T rather than a Some[T]. So if T is covariant with Foo, then Foo[T] should be a subtype of Foo[Option[T]]. But if you want that in Scala for instance, then it needs to be Foo[Some[T]] which seems a tad ridiculous in terms of overhead when I want to use a Foo that always returns a T in a situation that calls for a Foo that may return a T without some sort of shim.

This is nonsense.

T is not and should not be covariant on a context F whether it's Foo[T], Foo[Option[T]], or Option[T]. They all have significantly different meanings.

e: s/contravariant/covariant but really any variance.

sink fucked around with this message at 01:54 on Jul 8, 2015

Adbot
ADBOT LOVES YOU

Volte
Oct 4, 2004

woosh woosh

1337JiveTurkey posted:

Optional types feel half-assed when mixed with parametric polymorphism because while Foo[T] and Foo[Option[T]] may look closely related, they're nothing alike. Any situation where a method could return an Option[T], it should be equally valid to return a T rather than a Some[T]. So if T is covariant with Foo, then Foo[T] should be a subtype of Foo[Option[T]]. But if you want that in Scala for instance, then it needs to be Foo[Some[T]] which seems a tad ridiculous in terms of overhead when I want to use a Foo that always returns a T in a situation that calls for a Foo that may return a T without some sort of shim.
If Foo[T] is a subtype of Foo[Option[T]] then Option[T] is a subtype of Option[Option[T]] and the whole universe implodes

comedyblissoption
Mar 15, 2006

Bret Hart on null
https://www.youtube.com/watch?v=QgwTm1P37l4

Sinestro
Oct 31, 2010

The perfect day needs the perfect set of wheels.

Volte posted:

If Foo[T] is a subtype of Foo[Option[T]] then Option[T] is a subtype of Option[Option[T]] and the whole universe implodes

This is from my phone while I wait to get pizza, but isn't that just an implicit conversion via join :: (Monad m) => m (m a) -> m a? I mean, I guess you could make an Option[T] that didn't follow monad laws, but I'm pretty sure you'd have to a ctively try.

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!
Or duplicate : (Comonad w) => w a -> w (w a), whichever way you need to go. Seems perfectly fine.

KaneTW
Dec 2, 2011

code:
data Maybe a = Nothing | Just a

instance Applicative Maybe where ...
instance Functor Maybe where ...
done

Volte
Oct 4, 2004

woosh woosh

Sinestro posted:

This is from my phone while I wait to get pizza, but isn't that just an implicit conversion via join :: (Monad m) => m (m a) -> m a? I mean, I guess you could make an Option[T] that didn't follow monad laws, but I'm pretty sure you'd have to a ctively try.
In that case I guess-- I thought he was talking about actual subtyping, not just implicit conversions. It's still a mess, and implicitly wrapping and unwrapping optionals is missing the point of Option. I mean, it's not just about having an extra value to represent 'nothing' added into the type, it's really an algebraic data type (1+α), and that structure separating None from Some(α) is an inherent part of it. Hiding it just because we want to be lazy is exactly the thing we're trying to avoid.

1337JiveTurkey
Feb 17, 2005

Steve French posted:

How do you reconcile this at runtime, though? If you have something that depends on a Foo[Option[T]] returning Option[T], and you give it a Foo[T] returning T, what happens when you use that Foo and expect an Option[T] and call map on it, but instead you've been given a T? Does the compiler actually make your Foo[T] into a Foo[Option[T]] for you and wrap all your T instances with Some for you? Not saying this is intractable, just intrigued and wondering how you think it would work out in practice.

At any rate, having that be enforced at compile time is a pretty trivial issue; I've never been frustrated by it and it is really quite easy to just wrap the thing in an Option. I'd personally rather have an easy to fix compile time error than a lurking bug because I forgot an edge case because I'm a mistake-making idiot.

Sorry for the delay. At runtime it should be really simple since I'd treat None as a null reference, Some[T] as a non-null reference and Option[T] as a possibly null reference. So a method returning an Option[T] would be returning a plain old reference to T that's possibly null while a method returning Some[T] or just T would return a plain old non-null reference to T. Every T is an Option[T] but not every Option[T] is a T since they can also be None.

One consequence is that there's no way to distinguish None and Some[None] at runtime. There's also no way to distinguish T, Some[T] and Some[Some[T]] but I don't think those are meaningful, they're just artifacts of using wrappers. What we want is for Option[T] = T + None but implementations are really Option[T] = Some[T] + None. Programming languages with nullable references actually have T + None, the problem is that they don't have a way to distinguish it from T at compile time.

So instead of Option[T], Some[T] and None, I'd go with T, T? and None and make an explicit wrapper Option[T] which provides map etc while T? is just for pattern matching. For the sake of convenience there'd probably need to be some tweaks but ideally everything would use T? and then wrap it when they map it.

omeg
Sep 3, 2012

https://github.com/NyxStudios/TerrariaAPI-Server/blob/general-devel/Terraria/Player.cs#L21444

I know this is mostly decompiled code but :psyduck:

Jeb Bush 2012
Apr 4, 2007

A mathematician, like a painter or poet, is a maker of patterns. If his patterns are more permanent than theirs, it is because they are made with ideas.

1337JiveTurkey posted:

Sorry for the delay. At runtime it should be really simple since I'd treat None as a null reference, Some[T] as a non-null reference and Option[T] as a possibly null reference. So a method returning an Option[T] would be returning a plain old reference to T that's possibly null while a method returning Some[T] or just T would return a plain old non-null reference to T. Every T is an Option[T] but not every Option[T] is a T since they can also be None.

One consequence is that there's no way to distinguish None and Some[None] at runtime. There's also no way to distinguish T, Some[T] and Some[Some[T]] but I don't think those are meaningful, they're just artifacts of using wrappers. What we want is for Option[T] = T + None but implementations are really Option[T] = Some[T] + None. Programming languages with nullable references actually have T + None, the problem is that they don't have a way to distinguish it from T at compile time.

So instead of Option[T], Some[T] and None, I'd go with T, T? and None and make an explicit wrapper Option[T] which provides map etc while T? is just for pattern matching. For the sake of convenience there'd probably need to be some tweaks but ideally everything would use T? and then wrap it when they map it.

And you think it's worth all this messing around with your type system just to save 6 characters when someone wants to throw a T into an Option[T]?

e: And, as you mention, making it impossible to distinguish between your function failing to return data, and your function succeeding in returning data that happens to be a None from somewhere else.

Jeb Bush 2012 fucked around with this message at 18:21 on Jul 8, 2015

Impotence
Nov 8, 2010
Lipstick Apathy

isn't terraria the game where the server asked the client whether it should have admin privileges and peoples' public servers got demolished on the regular, all land destroyed, people spawn killed

i also remember that for a long time, you could effectively DoS the xna-based server .exe by just telnetting to the ip:port repeatedly and use up a player slot, and it would never be freed after you disconnect because you never sent some handshake

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Terraria, and possibly that very god class has come up before in this thread because it's such a pile of poo poo under the hood.

Soricidus
Oct 21, 2010
freedom-hating statist shill

Biowarfare posted:

isn't terraria the game where the server asked the client whether it should have admin privileges

lmao

omeg
Sep 3, 2012

I'm honestly wondering how they're able to update the game and even add some huge content patches and not break everything.

Impotence
Nov 8, 2010
Lipstick Apathy
Copy of terraria (2) real.cs.bak

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Biowarfare posted:

Copy of terraria (2) real.cs.bak

:airquote:version control:airquote:

Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

code:
# What a classy hack! Takes an object, returns the class of the object.
sub what_class {
    my ($object) = @_;

    # Split the string-ified object into class name and reference parts
    my ($class, $ref) = split(/=/, $object);

    return $class;
}
:suicide:

Soricidus
Oct 21, 2010
freedom-hating statist shill

John Big Booty posted:

code:
# What a classy hack! Takes an object, returns the class of the object.
sub what_class {
    my ($object) = @_;

    # Split the string-ified object into class name and reference parts
    my ($class, $ref) = split(/=/, $object);

    return $class;
}
:suicide:

ah, yes, perl, that language notable for lacking any standard built-in way to get the class of an object such as ref() or Scalar::Util::blessed()

how fortunate that nobody ever overloads the stringification operator, so this reliable hack can save the day

Bhaal
Jul 13, 2001
I ain't going down alone
Dr. Infant, MD
I'm sure the code behind this is unassailable in terms of quality of construction, yet I feel the need to lodge a complaint against gmail in here.

Here's part of the body of an email we send, as it appears in the gmail client (desktop version):



I blacked out the rest of the paragraph just to leave my company-specific stuff out. Now, in case you haven't had the pleasure, gmail only allows inline styles. linked css, <style> tags, media queries etc. are all eliminated. Also, they will ignore/overwrite certain style elements based on whatever context they decide to do that on, so you have to use "!important" all over the place to hopefully guard against that. Okay, if that was the worst of it I'd be more or less fine with it. I can push back on the design team to say their fancy responsive email templates just won't play nice with gmail. But now take notice in that image the <p> that encapsulates: "hi fred", a couple <br/>'s and then a paragraph of just plain text.

Check out that same email when viewed on gmail's site when it detects a mobile user-agent:



They completely changed up the html structure and broke it out of its home (which is too nested due to the WYSIWYG used to make these templates, I admit). Oh and to top it all off, that div they added around the br's and paragraph you'll note has class="gi ji". Yep gmail has styles for those:

CSS code:
 .ii, .ji {
  padding-top: 1em;
  color: #007b35;
}
So what I'm left with is a nice, fixed 600-width content area with gray/black text, and then this fugly green paragraph that breaks out of the content width and scrolls out to the full width of the viewport.

If there's some obvious advantage to all this that I'm not seeing that makes all this totally logical (or if I did something wrong like not add the header FuckWithEmailBody=false) then please let me know. I can totally get clearing js out of email and -some- stylesheet restrictions, but gmail is frustratingly aggressive in its manipulation.

Bhaal fucked around with this message at 01:46 on Jul 10, 2015

SupSuper
Apr 8, 2009

At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it.
HTML emails are a shitshow all around so the norm is pretty much to just embed as much of your content as possible into an image to avoid it getting mangled (with a "view in browser" link just in case).

necrotic
Aug 2, 2005
I owe my brother big time for this!

SupSuper posted:

HTML emails are a shitshow all around so the norm is pretty much to just embed as much of your content as possible into an image to avoid it getting mangled (with a "view in browser" link just in case).

Yeah, HTML emails are the horror alone. GMail isn't the only thing that has extreme restrictions on what is allowed in an HTML email: eg Outlook only supports a subset of HTML and only inline styles. I'm pretty sure the main reason for it is to reduce surface area for attacks, but lol.

nielsm
Jun 1, 2009



Bhaal posted:

I'm sure the code behind this is unassailable in terms of quality of construction, yet I feel the need to lodge a complaint against gmail in here.

Oh please.

That's got nothing on my old find in Apple Mail.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



The only other foolproof way (I can think of) to prevent malicious HTML email from loving with an HTML UI is to show the email body in an iframe, which I'd guess would make the HTML UI's memory footprint even worse for one thing.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

Apple's design ethic requires that customer-facing source code is fractal.

Space Kablooey
May 6, 2009


I'm on my phone now, but there was someone enumerating the geographical features present on that code iirc.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
that was about the fujifilm website

pseudorandom name
May 6, 2007

necrotic posted:

Yeah, HTML emails are the horror alone. GMail isn't the only thing that has extreme restrictions on what is allowed in an HTML email: eg Outlook only supports a subset of HTML and only inline styles. I'm pretty sure the main reason for it is to reduce surface area for attacks, but lol.

I thought they were using the Word layout engine to render the HTML.

Deus Rex
Mar 5, 2005

sarehu posted:

The answer is, unsurprisingly, you have to read libraries' API documentation.

What's API documentation?

SupSuper
Apr 8, 2009

At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it.
Meet Opa, the hot new language that combines every single web technology known to man! With such unique features as:

quote:

Typechecker: Opa unique feature is its advanced typechecker that automatically verifies your application code, looking for bugs and inconsistencies, and crunching debugging time.

Automatically? That's amazing, how do I get in on this wizardry? Let's look at the reference card:

code:
// function declaration
function int incr(int x) {
  x + 1
}

// type annotations for arguments and results can be omitted
function incr_alt(x) {
  x + 1
}
Well that looks simple enough.

code:
// manipulating (replacing/prepending/appending) DOM content for a given ID
#toto = <h1>Replace</h1>
#toto += <h1>Prepend</h1>
#toto =+ <h1>Append</h1>

// manipulating DOM selection
dom_pointer = Dom.select_children(#toto)
*dom_pointer += <h2>Before</h2>
Ok...

code:
// full record construction
john = { name: "John Smith", age: 31}
// accessing record fields
john_string = "Name: {john.name}, Age: {john.age}"

// tilde-shortcut
name = ...
age = ...
// '~field' within the record abbreviates 'field: field'
person = { ~name, ~age }
// one can even also abbreviate all fields by putting tilde in front of the record
person2 = ~{ name, age }
// both 'person' and 'person2' are equivalent to
person3 = { name: name, age: age }

// record extension
// meaning: take record 'john' and replace its 'age' field with the given value
older_john = { john with age: john.age + 1 }
Uh...

code:
// database values
database person {
  // it contains an integer value 'age'
  int /age
  // a float value 'weight'
  float /weight
  // and a string value 'name'
  string /name
}

// modifying
/person/age <- 37
/person/weight <- 76.5
/person/name <- "John Doe"
Wait.

code:
// Lists
database cities {
  list(string) /capitals
}

// Append one element
/cities/capitals <+ "Tokyo"
// Append several elements
/cities/capitals <++ ["Mumbai", "Delhi", "Shanghai"]

// Remove one element
/cities/capitals <--* "Tokyo"
// Remove several elements
/cities/capitals <-- ["Mumbai", "Delhi"]
Hold on a second.

code:
// Sets
type user_status = {regular} or {premium} or {admin}
type user = { int id, string name, int age, user_status status }

database users {
  user /all[{id}]

  // the status field is user-defined so we need to specify the default value
  /all[_]/status = { regular }
  // or to indicate that we will only manipulate full-records
  /all[_] full
}
aaaaaaaaaaaaaaaaaaaaaaaaaaa

DARPA Dad
Dec 9, 2008
#toto

Volte
Oct 4, 2004

woosh woosh

SupSuper posted:

aaaaaaaaaaaaaaaaaaaaaaaaaaa
The funniest part is that the two supported databases are MongoDB and, uh, Dropbox.

Soricidus
Oct 21, 2010
freedom-hating statist shill
/kansas/residents <--* #toto

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

Volte posted:

The funniest part is that the two supported databases are MongoDB and, uh, Dropbox.

Coding horrors: the two supported databases are MongoDB and, uh, Dropbox

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Opa's like four years old and peaked a while ago.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
That reminds me. I have, in my possession, source code written in an in-house scripting language, which looks like the most insane language known to man-kind. It looks like this:

code:
#base_instruction CreateBalloon(	id="ballooon2"	,shape="Rectangle"	,tail="None",rim_shape="Fade"	,log_bracket="None"
									,text_base="<FONT size=24 interval=70 speed=100 effect='Fade'>"	)
#base_instruction CreateImage(	z=50	)

unpass motion Main()
{
	CreateNode(	name="Space"	);
	CreateColor(	name="Space/C"	,w=800	,h=600	,color=blue	);
	Enter(	to="*"	);
	Enter(	to="*/*"	);
	call	Uni(time=2000,image="M_BLACK00.bmp",mask="M_wave01.bmp");
	WaitKey();
}
I have no idea what "unpass" or "motion" mean. Also note that HTML markup the engine uses to format text. And that blue is a keyword.

It also looks like this:

code:
class CItems 
{
	method CItems(bool $IsMemory=false, bool $IsSaveLock=false, bool $IsLoadLock=false)
	{
		CreateButton(name="EndGame"
			, x=100, y=560
			, key_left="Save,Load,BackLog"
			, group  ="SystemMenu", tab=0
			, class  =@CMenuItem(kind="EndGame", order=@EndGame()));
	}
}
(the rest of the class excluded for brevity)

The "@" seems to be a Lisp-like lambda here, which is always used for function calls or class construction. A way of passing a function call through to another layer. I think it's a neat idea.

And it also looks like this:

code:
@flip	time=0
-sprite	name="M1"	,obj="BLACK"	,y=-220
-sprite	name="M2"	,obj="BLACK"	,y=780
@back	obj="BLACK"	,time=0

@effect	at=@EffectExit( decor="Space/EF2"	,time=500	)
@wait time=500
@effect	at=@EffectDelete( decor="Space/EF2"	)
A Yaml-alike used for scene descriptions. Note the dual nature of "@" for both scene commands and the lambda syntax.

Oh, but of course, that can't only be it.

code:
scene Main()
{
	[S010100] ADV_MSG(script="010100.txt");
	[TITLE01] ADV_FFD(script="../TI/Title.txt",call=@Main(ch="0",num=1));
	[S011200] ADV_MSG(script="011200.txt");
	[EC011400] ADV_FFD(script="../EC/EyeCatch.txt" ,call=@Main(type=0));
	[S011700] ADV_MSG(script="011700.txt");

	operate $play_nSelectNumber=0;
	[S011800] ADV_MSG(script="011800.txt");
	if( $play_nSelectNumber==1 )
	{
		[S011801] ADV_MSG(script="011801.txt");
	}
	else if( $play_nSelectNumber==2 )
	{
		[S011802] ADV_MSG(script="011802.txt");
	}
	else
	{
		[S011803] ADV_MSG(script="011803.txt");
	}
}
I don't even at this point. I haven't figured out what the operate means. There's even more in this crazy rear end language, but I'll leave that for later.

By the way, I don't even think this language has a name. The binary that interprets it is just called "script.dll" and all of the scripts end in ".txt".

Suspicious Dish fucked around with this message at 02:26 on Jul 12, 2015

sarehu
Apr 20, 2007

(call/cc call/cc)
Is Opa an abbreviation of Opaka? Never name your proglang after a DS9 character.

Blue Footed Booby
Oct 4, 2006

got those happy feet


public bool puppy;

Edit: my scrolling thumb is tired and I'm nowhere near the bottom. This class is amazing.

Blue Footed Booby fucked around with this message at 13:42 on Jul 12, 2015

Workaday Wizard
Oct 23, 2009

by Pragmatica

sarehu posted:

Is Opa an abbreviation of Opaka? Never name your proglang after a DS9 character.

I thought it was named after the ship from Fantasy Zone.

VikingofRock
Aug 24, 2008




sarehu posted:

Is Opa an abbreviation of Opaka? Never name your proglang after a DS9 character.

drat, there goes my router config DSL called Captain Cisco.

Adbot
ADBOT LOVES YOU

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

sarehu posted:

Is Opa an abbreviation of Opaka? Never name your proglang after a DS9 character.

Agreed, but also, never call anything a "proglang".

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