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
Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

dc3k posted:

everything in linux is a file
everything in javascript is a god drat nightmare

Removed the spoilers, it's not a surprise to anyone at this point

Adbot
ADBOT LOVES YOU

Breetai
Nov 6, 2005

🥄Mah spoon is too big!🍌
Apologies for not contributing earlier.


code:

Select
num
, case when num/2 = int(num/2) then 'true' 
  else 'false'  
  end
  as iseven

from lnd.prd.db.allnums

Order by num

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


https://twitter.com/the_moisrex/status/1776661987855941776

Nolgthorn
Jan 30, 2001

The pendulum of the mind alternates between sense and nonsense

GABA ghoul posted:

I think there is a very clever solution for this that could save a lot of work

code:
if (number < 0)
 number = int.Parse(number.ToString().Replace('-', ''))

I want to know if I can get this through code review, don't tempt me Satan.

RPATDO_LAMD
Mar 22, 2013

🐘🪠🍆
what yall really need is some solid mathematical background for your IsEvens

Python code:
def isEven(x):
    return not isRelativelyCoprime(x, 2)
    
def isRelativelyCoprime(a, b):
    if b > a:
        a, b = b, a
    # if two integers a and b are coprime to each other, then
    # for all integers i and j,
    # b*i % a == b*j % a implies i % a == j % a.
    for i in range(0, a):
        for j in range(i + 1, a):
            if (i * b) % a == (j * b) % a:
                if i % a != j % a:
                    return False # found a counterxample!
    return True

it uses modulos, and it only takes quadratic time to run!

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

RPATDO_LAMD posted:

what yall really need is some solid mathematical background for your IsEvens

Python code:
def isEven(x):
    return not isRelativelyCoprime(x, 2)
    
def isRelativelyCoprime(a, b):
    if b > a:
        a, b = b, a
    # if two integers a and b are coprime to each other, then
    # for all integers i and j,
    # b*i % a == b*j % a implies i % a == j % a.
    for i in range(0, a):
        for j in range(i + 1, a):
            if (i * b) % a == (j * b) % a:
                if i % a != j % a:
                    return False # found a counterxample!
    return True

it uses modulos, and it only takes quadratic time to run!

My eyes just rolled into the back of my head

Foxfire_
Nov 8, 2010

I don't think I hate this that much? it's icky, but it's also plain what it does and how it works.

(I do hate that resume() returns 0 on both the first iteration and after it's finished)

Itaipava
Jun 24, 2007
In my head canon Duff's device was named after the Simpsons beer

QuarkJets
Sep 8, 2008

Foxfire_ posted:

I don't think I hate this that much? it's icky, but it's also plain what it does and how it works.

(I do hate that resume() returns 0 on both the first iteration and after it's finished)

The post of a broken man

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.

Foxfire_ posted:

I don't think I hate this that much? it's icky, but it's also plain what it does and how it works.

(I do hate that resume() returns 0 on both the first iteration and after it's finished)

One of the reasons I like the switch statement is how it breaks down into assembly pretty easily...

e.g.
code:
int x = // some value;

switch (x) {
    case 1:
        // Code for case 1
        break;
    case 2:
        // Code for case 2
        break;
    case 3:
        // Code for case 3
        break;
    default:
        // Code for default case
        break;
}
turns into something like
code:
; Assume 'x' is stored in the register eax
    mov eax, [x]      ; Move the value of x into eax
    cmp eax, 1        ; Compare eax with 1
    je case1          ; Jump to case1 if eax is 1
    cmp eax, 2        ; Compare eax with 2
    je case2          ; Jump to case2 if eax is 2
    cmp eax, 3        ; Compare eax with 3
    je case3          ; Jump to case3 if eax is 3
    jmp default_case  ; If none of the above, jump to default case

case1:
    ; Code for case 1
    jmp end_switch

case2:
    ; Code for case 2
    jmp end_switch

case3:
    ; Code for case 3
    jmp end_switch

default_case:
    ; Code for default case

end_switch:
    ; Continuation of code after switch
Pretty logical.

Using that construct in the screenshot is going to result in assembly language that looks like this:
code:
; Pseudo-assembly representation of the 'resume' function in the range_struct

; Assume 'this' pointer is passed in register ecx

resume:
    mov eax, [ecx + state]   ; Load the current state into eax
    cmp eax, At_start
    je  at_start
    cmp eax, In_loop
    je  in_loop
    cmp eax, Done
    je  done

at_start:
    mov dword [ecx + i], 0   ; i = 0
    mov eax, [ecx + stop]    ; Load stop value into eax
    cmp [ecx + i], eax       ; Compare i and stop
    jge done_label           ; If i >= stop, jump to done
    mov [ecx + state], In_loop   ; state = In_loop
    mov eax, [ecx + i]       ; Return i
    ret

in_loop:
    add [ecx + i], [ecx + step]  ; i += step
    mov eax, [ecx + stop]        ; Load stop value into eax
    cmp [ecx + i], eax           ; Compare i and stop
    jge done_label               ; If i >= stop, jump to done
    mov eax, [ecx + i]           ; Return i
    ret

done_label:
    mov [ecx + state], Done   ; state = Done

done:
    xor eax, eax              ; Return 0
    ret
So really gross for no good reason.

Volte
Oct 4, 2004

woosh woosh
I don't think there's anything that gross about it that's not also gross about any switch statement that uses fallthrough logic. The fact that it slices up the for-loop construct is kind of viscerally offputting but starting partway into the for loop isn't really conceptually any different than a do-while loop. It's what I would mildly classify as spaghetti code and not something I would ever do in general, but it's pretty clear what it does and how it works.

Soricidus
Oct 21, 2010
freedom-hating statist shill
The problem with it is that having a case statement in the middle of a loop is the kind of thing that might plausibly be undefined behavior or a compiler-specific extension. It’s obvious what the code intends to do, but it’s not a common idiom, so unless you’re familiar with the trick, it’s not obvious whether it will actually do that reliably, even if you run it and it seems to work on your machine.

That’s why it’s bad code.

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

Soricidus posted:

The problem with it is that having a case statement in the middle of a loop is the kind of thing that might plausibly be undefined behavior or a compiler-specific extension. It’s obvious what the code intends to do, but it’s not a common idiom, so unless you’re familiar with the trick, it’s not obvious whether it will actually do that reliably, even if you run it and it seems to work on your machine.

That’s why it’s bad code.

what.

duff's device is a little silly, but it's not against the spec

Hammerite
Mar 9, 2007

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

Soricidus posted:

The problem with it is that having a case statement in the middle of a loop is the kind of thing that might plausibly be undefined behavior or a compiler-specific extension. It’s obvious what the code intends to do, but it’s not a common idiom, so unless you’re familiar with the trick, it’s not obvious whether it will actually do that reliably, even if you run it and it seems to work on your machine.

That’s why it’s bad code.

I was going to say that it should be ok because no initialization of variables was being skipped, but actually it potentially is if I understand correctly.

The initialization of i to 0 occurs in the for loop header and it ought to run because the state is initialized to "at start" - but having said that, all the properties are public, so the user could construct one of these, then change the state and then call resume() to get it to run without i being initialized? But you could fix that by just initializing i to 0 along with all the other members so I don't know why the author didn't just do that.

Even if the enum member was (say) made private so that you couldn't do that, it seems like it's asking a lot of the compiler to prove that i isn't accessed before it's initialized? You would think the compiler would warn about it.

I guess in C++ both the "switch" and "for loop" language features translate pretty directly to labels and gotos, and it's clear how you convert that code into labels and gotos and it shouldn't cause any problems, so other than the uninitialized variable thing, I don't know how plausible it really is that it would be undefined.

It's a while since I touched C++.

Zopotantor
Feb 24, 2013

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

leper khan posted:

what.

duff's device is a little silly, but it's not against the spec

This is not really Duff's device though; it’s an implementation of a state machine or coroutine. In Duff's device the loop actually has a function, but here it would not really be necessary if the author had properly initialised "i" in the constructor.

efb

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

Zopotantor posted:

This is not really Duff's device though; it’s an implementation of a state machine or coroutine. In Duff's device the loop actually has a function, but here it would not really be necessary if the author had properly initialised "i" in the constructor.

efb

case statements in a loop have no issues

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
switch in C is unstructured control flow. The nested statement is just an ordinary statement block, and the associated cases can be recursively anywhere inside that block except (of course) within another switch; the switch jumps to the case, entering any scopes along the way and bypassing any earlier code in that scope. (In C++, bypassing initialized declarations is illegal, but otherwise it’s the same.) The only thing special about the switch statement block is that it’s the only statement block in the language that’s never possible to enter from the top.

for is structured control flow; there are no branches into arbitrary scopes. You just keep entering the loop body from the top as long as the condition expression evaluates to true.

You can desugar a for loop into labels and goto, but at some level that’s true of any local non-conditional control flow. You could desugar if statements into a more primitive “if … goto” instead of using nested blocks, and that would indeed look a lot more like assembly language; that doesn’t mean if isn’t a structured feature, it just means it has definable semantics.

rjmccall fucked around with this message at 21:02 on Apr 10, 2024

RPATDO_LAMD
Mar 22, 2013

🐘🪠🍆

Hammerite posted:

I was going to say that it should be ok because no initialization of variables was being skipped, but actually it potentially is if I understand correctly.

The initialization of i to 0 occurs in the for loop header and it ought to run because the state is initialized to "at start" - but having said that, all the properties are public, so the user could construct one of these, then change the state and then call resume() to get it to run without i being initialized? But you could fix that by just initializing i to 0 along with all the other members so I don't know why the author didn't just do that.

Even if the enum member was (say) made private so that you couldn't do that, it seems like it's asking a lot of the compiler to prove that i isn't accessed before it's initialized? You would think the compiler would warn about it.

I guess in C++ both the "switch" and "for loop" language features translate pretty directly to labels and gotos, and it's clear how you convert that code into labels and gotos and it shouldn't cause any problems, so other than the uninitialized variable thing, I don't know how plausible it really is that it would be undefined.

It's a while since I touched C++.


"this is bad because if you gently caress with internal object state you can put it in an invalid state" is a very "you're holding it wrong" kind of problem to have

the real problem is that it's using the switch as a fancy goto which is just fucky and unintuitive to read.
you could easily refactor this to use separate start(), loop(), done() functions instead of jumping into the middle of a block of shared code.

Soricidus
Oct 21, 2010
freedom-hating statist shill

leper khan posted:

what.

duff's device is a little silly, but it's not against the spec

I didn’t say it was against the spec. I know it’s not against the spec. I said it was the kind of thing that looks like it might be against the spec, and is bad code for that reason.

leper khan posted:

case statements in a loop have no issues

Coding Horrors: case statements in a loop have no issues

Hammerite
Mar 9, 2007

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

RPATDO_LAMD posted:

"this is bad because if you gently caress with internal object state you can put it in an invalid state" is a very "you're holding it wrong" kind of problem to have

It's not internal object state though, it's public. The language gives you the tools to make it internal, but the author of this code neglected to do that.

It's not like Python where everything is based on conventions and promises. If something is left public in C++ then the user is entitled to suppose that that means you intended for them to be able to modify it.

JawnV6
Jul 4, 2004

So hot ...

Bruegels Fuckbooks posted:

So really gross for no good reason.

well yeah but you chose x86 asm yourself

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Soricidus posted:

it was the kind of thing that looks like it might be against the spec, and is bad code for that reason.

This is me writing any line of C++. "But does this really work the way I think it does???"

Jen heir rick
Aug 4, 2004
when a woman says something's not funny, you better not laugh your ass off

pokeyman posted:

This is me writing any line of C++. "But does this really work the way I think it does???"

Breetai
Nov 6, 2005

🥄Mah spoon is too big!🍌
Our org uses SAS programs for regular scheduled reporting, and our data warehouse is a Teradata SQL environment that we can connect to using SAS EG. Generally speaking our programs are set up to to a whole bunch of data manipulation in Teradata, then bring refined datasets into the SAS grid in order to perform a few final transformations and then create the report outputs.

However, occasionally I will get a 'can you see why this program is running poorly' maintenance request and well...


So someone creates a SAS view via a connection to Teradata. Something like this:


code:
Proc sql;
<Teradata connection credentials>
Create view SASVIEW1 as select * from connection to teradata
(
Select <variables>
from <teradata table 1>

left join

	(select <variables>
	from <teradata table 2>

		left join

		(select <variables>
		from <teradata table 3>


			left join

			(select <variables>
			from <teradata table4>

on.....

)

And then they make HALF A DOZEN SAS views just like this. And then this happens:



code:
Proc sql;
<Teradata connection credentials>
crate table work.FINAL as
select * from connection to Teradata(

select * from SASVIEW1

union all

select * from SASVIEW2

union all

select * from SASVIEW3

union all

select * from SASVIEW4

union all

select * from SASVIEW5

union all

select * from SASVIEW6);

"Whycome my code run slow?" :gonk:

ExcessBLarg!
Sep 1, 2001
I wrote a for-case loop the other day for a project. At first I felt pretty bad about it but it's way better than these case-for shenanigans.

Volguus
Mar 3, 2009
Microsoft released the code for DOS 4.0 : https://github.com/microsoft/MS-DOS/

As expected, coding horrors :

code:
#define BEGIN    {
#define END      }
And, of course, their usage:

code:
char get_num_logical_dos_drives()
BEGIN

char   i;
...
END
Somebody really liked their pascal.

Kazinsal
Dec 13, 2011



code:
	cmp	AX, 04H 			; 04H and 08H are .exe and .com
	jl	rsrch_br1			; fuckin' sixteen-bit machine ought
	jmp	execute 			; to be able to handle a SIXTEEN-BIT
rsrch_br1:					; DISPLACEMENT!!
	jmp	batcom				; 02H is .bat
agreed, late 80s assembly-wrangler

darthbob88
Oct 13, 2011

YOSPOS
Request to the world: I'm going to do a presentation on magic in software development, using "magic" in the sense of "a system which you use but do not (fully) understand", and focusing on the occasions where that magic breaks down and causes problems for you, the developer using it. I need some examples, so- Please tell me about a time when a tool didn't work the way you expected it, and caused problems for you.

To give an example from my recent past, at a project I was working on a couple years ago, I tried to add a component to a module, but nothing appeared to change when I built the project. I brought the issue to my manager, who told me that the build system read from a configuration file to determine what components each module could use as a dependency, and I needed to add the component there as well as importing it in the module. I had assumed import Component from file; would be enough for the build tool to add it as a dependency, I was mistaken, and that caused a problem for me.

The thesis of the presentation at time of posting is mostly this koan, plus leaky abstractions and possibly this XKCD. "Magic abstractions are very useful, but they will trip you up if you don't know about them and a little about what they do under the hood".

Clanpot Shake
Aug 10, 2006
shake shake!

I've had to learn Spring recently and a lot of it boils down to "oh just add the @Magic annotation that you have to just know about." I was having compilation issues when I realized that the framework is so opinionated that it matters what you name things.

We're not even building anything complicated, just dumb REST apps.

QuarkJets
Sep 8, 2008

Floating point arithmetic is magic

darthbob88
Oct 13, 2011

YOSPOS

Clanpot Shake posted:

I've had to learn Spring recently and a lot of it boils down to "oh just add the @Magic annotation that you have to just know about." I was having compilation issues when I realized that the framework is so opinionated that it matters what you name things.

We're not even building anything complicated, just dumb REST apps.
Do you have any examples of names that Spring finds objectionable? Everything I can find on a quick search just says "We recommend standard Java naming conventions".

darthbob88
Oct 13, 2011

YOSPOS

QuarkJets posted:

Floating point arithmetic is magic

And most relevantly here, the fact that 0.1 + 0.2 != 0.3 is the sort of breaking abstraction I can use in my presentation.

lifg
Dec 4, 2000
<this tag left blank>
Muldoon
Git detached head. After a while I’ve gotten used to it. But I’ve gone from thinking of git as “version control” to “version control with a database with four types of objects each with specific properties.”

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


You can get weird behavior even with machine integers. The function that sends x to -x has two fixed points and that means you can't always assume that abs(x) > 0.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

darthbob88 posted:

Do you have any examples of names that Spring finds objectionable? Everything I can find on a quick search just says "We recommend standard Java naming conventions".

One of the ways to write your database access layer in Spring JPA is to declare an interface with methods like "List<User> findByEmailAddress(String emailAddress);". The method name is used to figure out what database field you're wanting to look up (since there could be many possible String fields in your database).

This works well enough if your queries are very simple and you know that that's what it's doing under the hood - which is unfortunate, because it might just be good enough to prevent you from switching to something that isn't completely insane.

OddObserver
Apr 3, 2009

ultrafilter posted:

You can get weird behavior even with machine integers. The function that sends x to -x has two fixed points and that means you can't always assume that abs(x) > 0.

Isn't there also some division by something other than zero that traps (as SIGFPE in Linux for bonus silly abstraction points)... sadly I am blanking on what it is by did run into it in sort of real life long time ago (grad school project)?

Edit: oh, I think it's basically the same thing aa you said. Found what I was thinking of in the GCC manual:

quote:

Integer division overflows in one specific case: dividing the smallest negative value for the data type (see Maximum and Minimum Values) by -1. That’s because the correct result, which is the corresponding positive number, does not fit (see Integer Overflow) in the same number of bits.

OddObserver fucked around with this message at 03:41 on Apr 29, 2024

Presto
Nov 22, 2002

Keep calm and Harry on.
Literally everything in git.

QuarkJets
Sep 8, 2008

Comment rot would be relevant here, there have been plenty of times that I've seen an elaborate set of lines commenting on how some tricky bit of code works and been like "uhh this doesn't work that way at all", then checked the git blame and found out that the comment was written 17 revisions ago

darthbob88
Oct 13, 2011

YOSPOS

Jabor posted:

One of the ways to write your database access layer in Spring JPA is to declare an interface with methods like "List<User> findByEmailAddress(String emailAddress);". The method name is used to figure out what database field you're wanting to look up (since there could be many possible String fields in your database).

This works well enough if your queries are very simple and you know that that's what it's doing under the hood - which is unfortunate, because it might just be good enough to prevent you from switching to something that isn't completely insane.
Oh wow. That's exactly the sort of thing I was looking for. It even neatly fits the framing I was planning to wrap the discussion of magic around, of both utility/convenience and restriction.

"Spring JPA allows you to skip writing the actual database access, because it will automagically generate the code for you based on the method names you use in the interface..."

"...so you have to make sure you name your methods the way Spring JPA likes, and heaven help you if you have any queries more complicated than 'getThingByProperty'."

Adbot
ADBOT LOVES YOU

CPColin
Sep 9, 2003

Big ol' smile.
Still beats writing all the lovely little queries by hand, imo

Either way, you really just have to get it right once and then you can stop thinking about it.

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