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
raminasi
Jan 25, 2005

a last drink with no ice
I thought making use of parse errors was generally considered cheating.

Adbot
ADBOT LOVES YOU

eth0.n
Jun 1, 2012

raminasi posted:

I thought making use of parse errors was generally considered cheating.

code:
#!/bin/sh

cat $0

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

eth0.n posted:

code:
#!/bin/sh

cat $0

Reading and printing the source code is definitely cheating.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender
code:

Works in quite a few different languages.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

raminasi posted:

I thought making use of parse errors was generally considered cheating.

a lot of things become possible when you stop assuming success

raminasi
Jan 25, 2005

a last drink with no ice

ShoulderDaemon posted:

code:
Works in quite a few different languages.

It even won a special "worst abuse of the rules" award in the obfuscated C contest. (They then changed the rules.)

ToxicSlurpee
Nov 5, 2003

-=SEND HELP=-


Pillbug

Suspicious Dish posted:

a lot of things become possible when you stop assuming success

I forget who said it but what I always thought was beautiful was the quote "the program can have any deadline you want if it isn't required to function."

antpocas
Jun 30, 2004

IF THIS POST ISN'T ABOUT GLORIOUS SALAZAR YOU MUST BE READING IT WRONG
There is a lot of legacy VB.NET code where I started working this month.

code:
    Private Shared Function CheckFlatRateShipCountry(ByRef randPercent As Double) As Double
        Try
            Dim query As String = "SELECT Percentagem FROM FarFlatRateShip Where CountryID=" & RegionalEngine.UserGeoPaisID & " AND Percentagem>0 "
 
            Dim percent As Double = 0
            FlatRateBRON(query, percent)
 
            randPercent = SpeedCache.GetDbValue(query, 0, 15)
 
            If percent <> 0 Then
                randPercent = percent
            End If
 
            Return IIf(randPercent = 0, False, True)
        Catch ex As Exception
            Return False
        End Try
    End Function
 
    Private Shared Sub FlatRateBRON(ByRef query As String, Optional ByRef percent As Double = 0)
        If IsTestEnvironment() Then
            If MarketManager.IsSiteBR() Then
                query = query.Replace("AND Percentagem>0", "")
                percent = 100
            End If
        End If
    End Sub

Space Kablooey
May 6, 2009


I'm the mixed English/Portuguese language codebase

Space Kablooey fucked around with this message at 13:44 on Jul 29, 2016

antpocas
Jun 30, 2004

IF THIS POST ISN'T ABOUT GLORIOUS SALAZAR YOU MUST BE READING IT WRONG

HardDisk posted:

I'm the mixed English/Portuguese language codebase
All the new stuff is written in C# and exclusively in English, but a lot of the VB.NET code still has these abominations. Sadly, mixed languages isn't the worst part, as you can see from basically every line of code in my post (the highlight is really the return type of CheckFlatRateShipCountry being double and it only returning booleans WHY DOES IT EVEN COMPILE)

redleader
Aug 18, 2005

Engage according to operational parameters
Here's a fantastic example of how to sensibly and appropriately use XSLT extension functions, straight from Microsoft.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
I was trying to figure out a good way to structure a class for dealing with whois records when I found this (C#)...:

code:
public class whois
{
    private string getWhoisServer(string tld)
    {
        string[,] whoisServers = new string[145, 2] {
            { "com", "whois.verisign-grs.com" },
            { "net", "whois.verisign-grs.com" },
            { "org","whois.publicinterestregistry.net" },
            { "info","whois.afilias.info" },
            { "biz","whois.neulevel.biz" },
            ...
        };
        if (tld == "com")
        {
            return whoisServers[0, 1];
        }
        else if (tld == "net")
        {
            return whoisServers[1, 1];
        }
        else if (tld == "org")
        {
            return whoisServers[2, 1];
        }
        else if ...
        else
        {
            return whoisServers[0, 1];
        }
    }

    ...
}

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

dougdrums posted:

I was trying to figure out a good way to structure a class for dealing with whois records when I found this (C#)...:

code:

public class whois
{
    private string getWhoisServer(string tld)
    {
        string[,] whoisServers = new string[145, 2] {
            { "com", "whois.verisign-grs.com" },
            { "net", "whois.verisign-grs.com" },
            { "org","whois.publicinterestregistry.net" },
            { "info","whois.afilias.info" },
            { "biz","whois.neulevel.biz" },
            ...
        };
        if (tld == "com")
        {
            return whoisServers[0, 1];
        }
        else if (tld == "net")
        {
            return whoisServers[1, 1];
        }
        else if (tld == "org")
        {
            return whoisServers[2, 1];
        }
        else if ...
        else
        {
            return whoisServers[0, 1];
        }
    }

    ...
}

There are like a dozen things wrong with that. Thanks for bringing the thread back on track.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
I helped him out and made a hashtable: +37 −618.

Holy poo poo I just realized that this gets called from a live public web service.

dougdrums fucked around with this message at 21:46 on Jul 30, 2016

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
What's even the reason for having the TLDs in the multidimensional array at all? That really looks like they started out with the code for a literal Dictionary<string, string> but didn't understand it, and dicked around with it until it worked.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
The other ones will do some sort of discovery to determine the proper server for the tld and then cache the result. Microsoft actually provides a library for dealing with bulk whois data on github here.

Ignoring the purpose for that method's existence, it is supposed to take a tld and look up its whois server, but, uh, there's a few odd decisions there. I have no idea what is going on in the rest of that program but
code:
private static readonly Hashtable whoisServers =
            new Hashtable {
                { "com", "whois.verisign-grs.com" },
                { "net", "whois.verisign-grs.com" },
                ...
            };
private static string getWhoisServer(string tld)
            => (whoisServers[tld]
            ?? whoisServers["com"])
            as string;

... would be my go, if you didn't want to look it up, use a mapped file, or a use database... and ignored the identifier naming convention ...

But, there are so many points he could have stopped at, a switch? Just returning the string? Maybe he had the array already formatted that way, and he thought that was the only way to access it without a lot of editing? Who knows.

dougdrums fucked around with this message at 03:32 on Jul 31, 2016

brap
Aug 23, 2004

Grimey Drawer
Every time I use a dictionary in C# it reminds me of how hosed it is to have all reference types be nullable, and how hosed it is to throw an exception for the rather routine case of a key not being in a dictionary, requiring any reasonable program to write dict.ContainsKey(key) ? dict[key] : null all the time

pseudorandom name
May 6, 2007

Reasonable programs use the TryGetValue method.

redleader
Aug 18, 2005

Engage according to operational parameters

dougdrums posted:

The other ones will do some sort of discovery to determine the proper server for the tld and then cache the result. Microsoft actually provides a library for dealing with bulk whois data on github here.

Ignoring the purpose for that method's existence, it is supposed to take a tld and look up its whois server, but, uh, there's a few odd decisions there. I have no idea what is going on in the rest of that program but
code:
private static readonly Hashtable whoisServers =
            new Hashtable {
                { "com", "whois.verisign-grs.com" },
                { "net", "whois.verisign-grs.com" },
                ...
            };
private static string getWhoisServer(string tld)
            => (whoisServers[tld]
            ?? whoisServers["com"])
            as string;
... would be my go, if you didn't want to look it up, use a mapped file, or a use database... and ignored the identifier naming convention ...

But, there are so many points he could have stopped at, a switch? Just returning the string? Maybe he had the array already formatted that way, and he thought that was the only way to access it without a lot of editing? Who knows.
Agreed, if by "Hashtable" you mean "IReadOnlyDictionary" or (preferably) "ImmutableDictionary".

brap
Aug 23, 2004

Grimey Drawer

pseudorandom name posted:

Reasonable programs use the TryGetValue method.

They're both basically bad. One of them requires declaring more variables and having if statements for each dictionary access. The need for Try* methods is a sign of the shortcomings of the language.

Actually I have to wonder how many people's Utils files add a GetValueOrDefault which basically calls TryGetValue and returns default(TValue) if the key isn't present.

sarehu
Apr 20, 2007

(call/cc call/cc)

fleshweasel posted:

They're both basically bad. One of them requires declaring more variables and having if statements for each dictionary access. The need for Try* methods is a sign of the shortcomings of the language.
No it's just what a sensible minimum-surface-area API would be...

fleshweasel posted:

Actually I have to wonder how many people's Utils files add a GetValueOrDefault which basically calls TryGetValue and returns default(TValue) if the key isn't present.
Or better yet takes the default value as an argument.

1337JiveTurkey
Feb 17, 2005

redleader posted:

"IReadOnlyDictionary"

Proof of the need for more literature and grammar classes in our schools :v:

brap
Aug 23, 2004

Grimey Drawer
Try* can be useful but requiring you declare variables and execute if statements can be quite inconvenient if you're doing LINQ or something. Try* exists because the language has only lovely, ad hoc ways of representing a value which might not be present.

Throwing exceptions on dictionary accesses and when parsing numbers from strings was a boneheaded decision by the .NET standard library designers.

Yes, GetValueOrDefault could/would/should parameter use the default value but use default(TValue) as the default, and people would occasionally pass different values.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)

redleader posted:

Agreed, if by "Hashtable" you mean "IReadOnlyDictionary" or (preferably) "ImmutableDictionary".

I forgot about IReadOnlyDictionary, thanks for reminding me. I've been using the immutable namespace, but didn't think it was standard. This MSDN page clears up the issue though.

fleshweasel posted:

They're both basically bad. One of them requires declaring more variables and having if statements for each dictionary access. The need for Try* methods is a sign of the shortcomings of the language.

Actually I have to wonder how many people's Utils files add a GetValueOrDefault which basically calls TryGetValue and returns default(TValue) if the key isn't present.

I've seen a couple NullDictionary classes...

C# 6 had a proposal for declaration expressions, which were supposed to 'solve' this problem, but it was dropped.

With the addition of expression-bodied functions, Try* functions are really silly, but there's alternatives to dictionary that already work ok.

I think having dictionary throw an exception when it doesn't have the key is meant to support stuff like member lookup of dynamic objects.

dougdrums fucked around with this message at 11:03 on Jul 31, 2016

comedyblissoption
Mar 15, 2006

exceptions are bad

all references being nullable is bad

not having sum data types is bad

but all mainstream programming languages sin on one of the above points

welp

Athas
Aug 6, 2007

fuck that joker

comedyblissoption posted:

exceptions are bad

This one is pretty hard to fix if you want to run your program on real hardware. How do you deal with out-of-memory, stack overflow, or other "impossible" situations? The only way out is to replace exceptions with unhandleable panics (which is the right thing to do).

john donne
Apr 10, 2016

All suitors of all sorts themselves enthral;

So on his back lies this whale wantoning,

And in his gulf-like throat, sucks everything

That passeth near.
Plus if I didn't have exceptions, how would I control the flow of my application?

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

antpocas posted:

(the highlight is really the return type of CheckFlatRateShipCountry being double and it only returning booleans WHY DOES IT EVEN COMPILE)

as with nearly everything that's hosed up in VB.NET, the answer is "you didn't activate option strict in your project"

booleans at least are safely convertible to double so this isn't even that bad

honestly the "who needs to write functions when I can add ByRef to a subroutine" anti-pattern bothers me way more and it seems pathologically ingrained in the habits of old delphi / VB6 dudes

NihilCredo fucked around with this message at 14:37 on Jul 31, 2016

Linear Zoetrope
Nov 28, 2011

A hero must cook

Athas posted:

This one is pretty hard to fix if you want to run your program on real hardware. How do you deal with out-of-memory, stack overflow, or other "impossible" situations? The only way out is to replace exceptions with unhandleable panics (which is the right thing to do).

I think it's reasonable to be able to catch panics, just so you can attempt to launch into a "woah, something went wrong!" error message/reporting tool for the user instead of an unceremonious CTD with a reason stored in a log file somewhere, but recovering from something that forces the stack to unwind should be used extremely rarely, only at the topmost level of the program, and pretty much never in libraries. (The only exception I can think of in libraries is Rust's use of detecting current panics in the Mutex Guard destructor in order to poison a mutex, but that's detection more than it is catching)

Linear Zoetrope fucked around with this message at 15:05 on Jul 31, 2016

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
try/finally is good

try/catch is bad

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

sarehu posted:

Or better yet takes the default value as an argument.

It always mystifies me why standard library map objects don't have a map.get(key, valueIfNotFound) method. The need for such a method is incredibly common and yet many map types don't provide it.

Hughlander
May 11, 2005

Athas posted:

This one is pretty hard to fix if you want to run your program on real hardware. How do you deal with out-of-memory, stack overflow, or other "impossible" situations? The only way out is to replace exceptions with unhandleable panics (which is the right thing to do).

My quote is always, "Exceptions are for exceptional cases." A stack overflow is exceptional, a key missing from a map is not.

Carbon dioxide
Oct 9, 2012

Hughlander posted:

My quote is always, "Exceptions are for exceptional cases." A stack overflow is exceptional, a key missing from a map is not.

Good coding practices are exceptional.

Absurd Alhazred
Mar 27, 2010

by Athanatos

Carbon dioxide posted:

Good coding practices are exceptional.

Unhandled exception at 0x49a3811f: Unexpected good coding practice.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

Hughlander posted:

My quote is always, "Exceptions are for exceptional cases." A stack overflow is exceptional, a key missing from a map is not.

I think dictionaries can legitimately be used in both ways. Sometimes you expect the key lookup to fail in the course of normal operations, but often enough you build and use dictionaries in such a way that failed lookups shouldn't happen and if they do it's a bug. In that case you don't want an error path, you want an exception.

Returning an option type is still the much better option because to get the second kind of behaviour you just need to call .Value on the result to unsafely unwrap it; as opposed to the current situation where if you want the first kind of behaviour you need to cumbersomely (and thread-unsafely) go through .ContainsKey().

comedyblissoption
Mar 15, 2006

Hughlander posted:

My quote is always, "Exceptions are for exceptional cases." A stack overflow is exceptional, a key missing from a map is not.
Yeah but you are totally hosed when the standard library itself promotes abusing exceptions for this type of control flow for one of its most fundamental data structures which propagates to every third party library and framework you are ever going to use.

In C#, you can reach a situation where you have no idea what exceptions some dependency may throw as part of what should be normal control flow if you do not have the full source code of that dependency and its dependencies. You have to rely on potentially erroneous or out of date documentation if it exists. Software a third party vendor codes to an interface may surprise you and not match what the interface is supposed to do! The dependency that you have no control over may throw Exception for general control flow exceptions! Yay! What often ends up happening is you say gently caress it and just catch Exception instead of specific "control flow" exceptions.

The fundamental problem with exception abuse is that mainstream languages lack a good way to handle propagating and handling "control flow" errors. There's always some dumb and inconsistent ad hoc bullshit every single loving time.
  • Check a global error value so that you're hosed if you want concurrency
  • Return an error code. The actual output you want might be stuffed in an input parameter you pass. Now you need to look up the success cases in case they did something non-conventional and fun!
  • Return the output for normal control flow but it has a nonsensical value in error cases. You pass in an input parameter that represents error output.
  • Return a bool so that now you have to look up if true means success or not.
  • Return some wrapper struct and hope the caller is disciplined enough to always handle the error cases properly
  • Abuse exceptions for control flow
  • Combine exceptions and/or one or more of the above for a clusterfuck

obviously the solution is sum types

Soricidus
Oct 21, 2010
freedom-hating statist shill
Exceptions are fine. Good luck finding an alternative that bad programmers can't gently caress up just as badly as they gently caress up exceptions.

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer
The Maybe and Either types clearly solve almost all of these problems, but something akin to exceptions is still needed for fatal stuff like stack overflows, out-of-memory, etc. (You probably don't want every single function in your program to be on the form f :: a -> Either FatalError b.) Exceptions are arguably also okay for stuff like IOException, i.e. what Eric Lippert calls "exogenous" exceptions: https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/. Exogenous exceptions are technically the only type you should ever actually catch in your code, except when you're forced to use a badly designed API, which in .NET sadly includes various parts of the standard library.

Soricidus posted:

Exceptions are fine. Good luck finding an alternative that bad programmers can't gently caress up just as badly as they gently caress up exceptions.

I'm pretty sure bad programmers would gently caress up far less with the Either monad than they currently do with exceptions, but sum types really have to be somewhat baked into the syntax of a language (e.g. pattern matching) to be viable. Otherwise you're just kicking the exception can down the road, and you'll probably gently caress up your error message too because the message is generated when you inspect the result instead of when you calculate it.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
There is nothing wrong, in general, with using exceptions for control flow. (Some projects/language communities adopt the convention that you shouldn't use exceptions for control flow, and they're wrong, but not outrageously so; so you should abide by that convention when working on that project, just as you'd abide by any other specified convention.)

Adbot
ADBOT LOVES YOU

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Hammerite posted:

There is nothing wrong, in general, with using exceptions for control flow. (Some projects/language communities adopt the convention that you shouldn't use exceptions for control flow, and they're wrong, but not outrageously so; so you should abide by that convention when working on that project, just as you'd abide by any other specified convention.)

Except if you actually want to debug the code.

One of the things I like to do when poo poo just "doesn't work" is go into the debugger, and turn on "break on all exceptions." This is very helpful to find problems where people are catching exceptions when they shouldn't have and logging them to unexpected places.

If you have exceptions in the control flow, I have to learn where the expected exceptions are, put the breakpoint after those, run, and then see if I find the real uncaught exception. This makes debugging take a lot longer and just sucks.

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