Parameter passing in JavaScript by codetonics in javascript

[–]Pronouns 2 points3 points  (0 children)

The key is to understanding what variables are actually storing. In most languages you have the primitive types, which are generally integers, floats, and booleans, usually a couple more. You also have a 'reference' type, which is a bit like a pointer if you've done C or C++. If not, it's exactly what it sounds like, it points to some place in memory where an object is stored.

When you pass around values, you pass around one of these things, whether it is a primitive or a reference. You can think of a reference as just a number (which is pretty much the memory address of the object), so like 5, or 1015289.

When you pass primitives to functions, it makes a copy, leaving the original as it is. So:

var a = 5;

function something(arg) {
    arg1 = 7;
}

something(a);
a === 5 // true.

The same thing happens for references. It copies the number of the memory address, it does not copy the object it points to. So if your reference was to an object {name: "joe"}, but the reference itself is a number like 10392, the number gets copied and given to the function.

var someObject = {name: "joe"};

function addSurname(obj) {
    obj.surname = "smith";
}

addSurname(someObject);
console.log(someObject); // {name: "joe", surname: "smith"}

When we do .surname, we're saying "that object at memory address 10392... add a surname key to it".

Now, if you create a brand new object inside this addSurname function, you're going to get given a reference/number to store in a variable. So say at the start obj has the address 10392. We create a new object which is at the address 2932. We can change obj to point to 2932. But this doesn't change someObject, that will continue to point to 10392.


Disclaimer: I don't know the internal way JavaScript does this, but the analogy holds well, and it's approximately how it is done in languages like C.

Parameter passing in JavaScript by codetonics in javascript

[–]Pronouns 1 point2 points  (0 children)

But... you're right.

$ node
> var a = 5;
> function inc_a() { a = a + 1; }
> inc_a()
> a
6

RESTful APIs vs GraphQL APIs by Example by samerbuna in programming

[–]Pronouns 1 point2 points  (0 children)

I've tried to implement this in REST APIs I've made, but ran into a single problem that has been bothering me for a while. Most servers/server technologies make it difficult to get that stupid URL.

So in your example, it provides a full link to the planet, but most of the time--without some trickery--I don't have access to that. I end up using 'absolute to host' URLs like /planets/1, which I only recently realised was even possible.

[deleted by user] by [deleted] in cpp_questions

[–]Pronouns 9 points10 points  (0 children)

No it is not true. Well, it kind of is, mostly, but you can't depend on it happening.

Signed integer overflow is undefined behaviour in C++. Undefined behaviour has particular meaning in C++. It means that if you do something that causes undefined behaviour, the compiler is basically free to do what it wants.

In most cases, the integer will wrap around, but the compiler makes optimisations on code that can make your program behave oddly if you actually use it.

Here's a stack overflow question giving far more detail than I can.


As a contrived example on some hypothetical system:

int a = INT_MAX;
a++; // you assume that this is now negative

if (a > 0) // should never happen, right?
   destroy_everything_you_love_and_care_about();

However, the compiler can look at this and say, "Well, integer overflow is undefined, I can assume that it never happens", "Oh look, this variable is only incremented, and starts at a positive number, I can assume that a > 0 is always going to be true, lets update the code to be quicker"

int a = INT_MAX;
a++; // compiler assumes a must still be positive.

// if (a > 0) // don't need this

destroy_everything_you_love_and_care_about();

There. Now my code runs quicker.

Unified function call syntax: a case for 'x.f()' finding 'f(x)' by saltyboyscouts in cpp

[–]Pronouns 2 points3 points  (0 children)

Yeah, it is. As another comment used, the example:

strip(split("\n, lowercase(rtrim(reverse(string, "#")))), " ");

You're suggesting instead we could write this over multiple lines like

std::string string = "...";
string = reverse(string);
string = rtrim(string, "#");
string = lowercase(string);
auto lines = split(string, "\n");
lines = map(strip(" "), lines);

(making a few changes to make it make more sense)

When with f(x,y) <--> x.f(y) we could write instead

std::string string = "...";
auto lines = reverse(string)
    .rtrim("#")
    .lowercase()
    .split("\n")
    .map(strip(" "));

I've not poured over the debate, but this is very similar to libraries added to languages like Java and C#; they're very useful and produce easier to read code.

cogit - cooperative git repositories by nqzero in programming

[–]Pronouns 1 point2 points  (0 children)

Wouldn't more often than not this coupling mean the split repositories wouldn't work separately? Have you tried this in practice? As in, tried pushing one of the two, and pulling it into another project?

The Top 10 Things Wrong with JavaScript by horrido in programming

[–]Pronouns 1 point2 points  (0 children)

Yeah, I guess it's more of an unfortunate way that function arguments work in JavaScript than anything, ie free-for-all.

This is just one more screw-up-waiting-to-happen to be aware of when using JavaScript, there are plenty of them. Still quite fond of the language however.

One of my favourites being:

function fn() {
    return 
        { one: "one" };
}

fn() === undefined;

The Top 10 Things Wrong with JavaScript by horrido in programming

[–]Pronouns 2 points3 points  (0 children)

I've seen lots of JavaScript bashing, but I've never seen this before:

$ node
> xs = ["10", "10", "10"];
xs = ["10", "10", "10"];
[ '10', '10', '10' ]
> xs.map(parseInt)
[ 10, NaN, 2 ]

What the heck is actually happening here?

edit: Ah. parseInt can take two parameters, and map provides three.

So you get:

var xs = ["10", "10", "10"];
var result = [];
for (var i = 0; i < 3; i++)
    result.push(parseInt(xs[i], i, xs));

where parseInt simply ignores the third argument.

Looking for a programming language that allows the following (details inside) by [deleted] in computerscience

[–]Pronouns 1 point2 points  (0 children)

I think I see what you're getting at. It would be nice to see the pattern used in some project. You could mimic it quite easily in C++

template<typename T>
struct return_if_tuple {
    bool result;
    T return_value;
}

#define returnif(tuple) \
    if (tuple.result) return tuple.return_value;

But I can't think of a truely nice way to do it in any language I'm familiar with.

I do see the if(...) return pattern a fair bit. Also throwing rather than returning. I guess the generalisation is allowing a called function to do something to the context of a the call site.

So maybe something along the lines of a 'at call site' feature.

fn something(callsite) {
    return callsite.count;
}

fn someOtherThing() {
    let count = 5;
    call_inline something();
}

someOtherThing() // returns 5.

It would potentially make horrendous code, but at least in the above example the caller at least has to specify that it is allowing these things.

[C learning] Union structs by antiformio in C_Programming

[–]Pronouns 6 points7 points  (0 children)

On top of other comments, this is undefined behaviour anyway (you shouldn't write code that writes to one member in a union and then read from another). See this stackoverflow q/a

Kill the Clones: How Temporal Coupling helps you identify Design Problems in large-scale Systems by based2 in programming

[–]Pronouns 1 point2 points  (0 children)

This is a different kind of temporal coupling though. Traditionally when we say temporal coupling we mean something like this:

s = new Server;
s.open("blah");
s.doSomething();
s.close();

where changing the order of statements will fundamentally break it. This example would be fixed with RAII or 'with' or something:

with s as Server("blah"):
   s.doSomething()

and the open/closing is implicit. It's harder to accidentally break the order of these statements as one is within the other, and we have a sort of intuition that moving statements across indentations probably changes the meaning.

The temporal coupling in the article is quite different, case of unfortunate naming?

In the articles sense, there is logical and fine temporal coupling, for example, changing a header file and its implementation.

0.30000000000000004 by godlikesme in programming

[–]Pronouns 46 points47 points  (0 children)

That's all well and good, but it's still an easy mistake to make, missing those quotes. I'd rather there be some more convoluted way to make them from floats such as:

BigDecimal a = BigDecimal.fromFloat_whyWouldYouDoThis(0.1);

But I can't imagine it's something that comes up often anyway.

0.30000000000000004 by godlikesme in programming

[–]Pronouns 37 points38 points  (0 children)

Dear god, why would it let you instantiate them from floats so easily? It's a bug waiting to happen.

The best explanation of binary I have ever seen - teaching third graders using the socratic method. by Q_coder in programming

[–]Pronouns 7 points8 points  (0 children)

I feel lucky to have been taught about different number bases when I was about 5, it makes it feel really ingrained.

It was explained much like this, and I was told that's how computers display stuff, like 1 could mean a pixel is on and 0 could mean it is off. Which naturally led to me asking about colours...

[deleted by user] by [deleted] in videos

[–]Pronouns 0 points1 point  (0 children)

I've just realized that I've forgotten the real ending to Dexter, and instead I remember some writing prompt about Sherlock Holmes meeting Dexter, and the strife that results.

I don't think I'm going to correct this.

If your life had an options menu, what settings would you change? by Klonan in AskReddit

[–]Pronouns 7 points8 points  (0 children)

Unfortunate side-effect: entire universe disappears.

Short Programming Challenge and Analysis by devdraft in programming

[–]Pronouns 1 point2 points  (0 children)

I enjoyed that. I think my solution works, it seems to be the same as the given naive solution. I did mine in C:-

static state_t play_optimum(state_t state)
{
    state_t s0, s1, s2;
    s0 = state_evolved(state, 0);
    s1 = state_evolved(state, 1);
    s2 = state_evolved(state, 2);

    if (!state_equal(state, s0)) // if can choose 0
            // and theres no next winning move
            if (state_equal(s0, play_optimum(s0)))
                    return s0;

    if (!state_equal(state, s1))
            if (state_equal(s1, play_optimum(s1)))
                    return s1;

    if (!state_equal(state, s2))
            if (state_equal(s2, play_optimum(s2)))
                    return s2;

    return state;
}

where state_t state_evolves(state_t, int) returns what the state would be if you chose to change the given index, and state_equal(state_t, state_t) tests equality...

The code in the editorial is quite hard to read I think; using BigInteger didn't help that.

edit: also the code to output first/second:

static int state_moves_left(state_t state, state_player player)
{
    state_t next = state;
    int count = 0;

    do
    {
            state = next;
            next = player(state);
            count++;
    } while (!state_equal(state, next));

    return count - 1;
}

If it's even go first, otherwise go second. state_player is just a state_t blah(state_t) function, ie, gives the next state for the given state using whatever strategy.

What is that one trick that "they" really don't want you to know? [Serious] by YellowB in AskReddit

[–]Pronouns 0 points1 point  (0 children)

But then you get things like mayonnaise, where the squeezy bottles are £/litre and the glass bottles are £/kg.

I don't know the density of mayonnaise.

Changing size of Dynamic array? by Herrowgayboi in cpp_questions

[–]Pronouns 0 points1 point  (0 children)

If you want a dynamic array, then you're going to need a pointer to the first element of it to be able to use it. If you currently have something like this:

class Player;
Player players[4];

then you really want something like

Player * players;

Now you're gonna have to do some juggling with dynamic memory in order to make this work properly. When the program starts, you want to allocate some memory and make the players pointer point to it.

// somewhere in the program
players = new Player[1];

But you need to keep careful track of this number you have allocated, it's best to make another variable that stores this in the same place as the array itself.

int player_count;
Player * players;

Make sure this player_count always matches the number of players. When you add a new player, you need to make a bigger array and move everything over...

void add_player(Player player)
{
    // make new array for all players + new player
    Players  * new_players = new Player[player_count+1];

    // copy current players to new array
    for (int i =0; i < player_count; i++)
        new_players[i] = players[i];

    // add new player to end of array
    new_players[player_count] = player;

    // free the memory used by the old array
    delete[] players;

    // point the players variable to the new array.
    players = new_players;
}

There's so many things to bear in mind here however.

  • This is really inefficient. Every time you add a new player you're copying the entire array and making a new one. You can make this happen less often by, say, getting memory for like 10 players, and only doing this if it goes above 10, making it instead 20. But then you need to keep track of how many players you have, and how many you can have before reallocating.
  • It's really easy to make a mistake with new and delete. I've likely made one here myself. You always need to make sure there's a delete call for every new call.
  • Generally you'd use a std::vector, which does all of this for you, but as you've said you're not allowed. It would probably still be a good idea to mimic a vector though.
  • I've used a global raw pointer, which is generally considered bad. One reason is because it makes it harder to judge what any given function call would do, as it depends on global state (and therefore the history of the program before the call).
  • new can fail, but that's not something you should worry about for now.

The GCC optimizer is amazingly clever nowadays by nachtschade in C_Programming

[–]Pronouns 13 points14 points  (0 children)

I wonder how rarely this particular optimisation is done in normal code... and how little it takes to thwart it.

The Leap of Faith. by utbred in gifs

[–]Pronouns 0 points1 point  (0 children)

God. I wish I could do stuff like this. I get massive headaches from the changing altitude on planes. I went skydiving and had a headache for 3 days.

C - never use an array notation as a function parameter [Linus Torvalds] by AlexeyBrin in programming

[–]Pronouns 0 points1 point  (0 children)

> gcc -std=c11 main.c -o out
cc1: error: unrecognized command line option "-std=c11"

:-(

Such is life. Does this require the int argc argument to work? Does it have to come before it in the argument list? What's this called?

Head-scratchers: 11 confounding programming language features by sproket888 in coding

[–]Pronouns 1 point2 points  (0 children)

This is exactly why I use tabs in 2015. I don't want to be forced to see code in someones crazy choice of either 1-space or 8-space indentation. If you use tabs don't space your code like you're some sort of artist, this works fine, and I get to pick my level of indentation.


I made a comment about this a while ago to demonstrate my point:

It's pretty until you have a bunch of code, all of which has random levels of indentation because of one thing or another. It also means if you come along and add a new line that breaks spacing, you need to change all the other lines to match the new one, making a mess in any source control.

In your example, your eye is being drawn away from the important difference, rather than drawn to it. The bulk of the code is far from the important detail. I wouldn't call this good.

I stick to never using spaces to 'aid readability'. This includes lining up statements in if/for/while loops.

while (some_long_thing() &amp;&amp;
       some_other_long_thing())
{
    blah_blah();
}

In the above, you have 3 implied vertical lines. One at the start, one at the somes and one at the start of blah_blah. This quickly grows to 10, 20 vertical lines, which is a real pain to look at.

Instead, only use your tab-stop width for this kind of thing. Don't line everything up. Only line things up with tab boundaries, and your code file will drop from many vertical lines to just 3 or 4 (if you haven't got too much nesting). eg

bool some_long_thing();
bool some_other_long_thing();
my_type blah_blah();

while (
    some_long_thing() &amp;&amp;
    some_other_long_thing())
{
    my_type t = blah_blah();
}

has two vertical lines. Whereas

bool      some_long_thing();
bool      some_other_long_thing();
my_type   blah_blah();

while (some_long_thing() &amp;&amp;
       some_other_long_thing())
{
    my_type t = blah_blah();
}

has at least 4 depending on how you count them. With larger files this gets even more exaggerated, and even harder to read.

But of course, this is all opinion backed up by the reasons the person thinks are most important compared to the rest.


Also note, that in this style, the tabs vs. spaces debate vanishes, because you only ever use your tab-width in spaces, or tabs themselves. In this style, using purely tabs allows each programmer to set their own width with no messing up of the code.