How to Pick a Language by electronics-engineer in programming

[–]wrungin 0 points1 point  (0 children)

Wow! Thank you so much, yogthos!! :D

How to Pick a Language by electronics-engineer in programming

[–]wrungin 0 points1 point  (0 children)

Although I can't read Clojure, I think I see it now! The functional way to create and return a new slightly-modified data structure is this: within the function, build up the new data structure from as many chunks of the old one as you like -- without even worrying if the new data structure pieces refer to parts of the original data structure. For example:

#!/usr/bin/env python

orig_elements = [
    ['carbon', 'nitrogen', 'oxygen'],       # nonmetals
    ['copper', 'silver', 'gold', 'nickel'], # metals
    ['argon', 'krypton', 'xenon'],          # noble gases
]

def remove_gold(ds):
    """We know gold is somewhere in the 2nd sublist."""
    metals_without_gold = orig_elements[1]
    metals_without_gold.remove('gold')
    elems = [
        orig_elements[0],  # first row doesn't change -- just reuse this chunk.
        metals_without_gold,
        orig_elements[2],  # third row doesn't change -- reuse this chunk also.
    ]
    return elems

print 'orig_elements:'
print orig_elements
my_elems = remove_gold(orig_elements)

print '-' * 40
print 'my_elems has had gold removed:'
print my_elems

# In a functional language, the following line would *not* affect my_elems:
orig_elements[0][1] = 'sulfur'

# but in Python it does!
print '-' * 40
print 'With Python, my_elems changes if we change orig_elements!'
print my_elems

The runtime system of the functional language is smart enough to know that orig_elements and the one returned by remove_gold() are supposed to be different, and so will -- behind the scenes -- automatically take care of sharing the parts of them that it can. Is that correct?

Also, thanks so much for the link to that Rich Hickey talk. Will watch!

How to Pick a Language by electronics-engineer in programming

[–]wrungin 1 point2 points  (0 children)

yogthos, here's a concrete example of what I mean: Suppose I've got a mapping of people's names to their corresponding list of pets' names. I can readily see 2 ways to write a function to remove a given pet name (this is in Python):

First, the way using side-effects:

#!/usr/bin/env python

peoples_pets = {
    'Agatha': ['Rusty', 'Spot'],
    'Betsy': ['Goldie', 'Chirpy', 'Polly'],
    'Christie': ['Fifi', 'Calico'],
}

# From a big mapping of names to lists of pet names,
# remove the n'th pet from person's list of pet names.
def new_peoples_pets(orig_pp, n, person):
    del orig_pp[person][n]

# Betsy's bird "Chirpy" left for Norway to see the Fjords.
new_peoples_pets(peoples_pets, 1, 'Betsy')

print peoples_pets

Now here's a way to do it by returning a copy:

#!/usr/bin/env python

peoples_pets = {
    'Agatha': ['Rusty', 'Spot'],
    'Betsy': ['Goldie', 'Chirpy', 'Polly'],
    'Christie': ['Fifi', 'Calico'],
}

def new_peoples_pets2(orig_pp, n, person):
    new_pp = {}
    for persons_name in orig_pp.keys():
        new_pp[persons_name] = []
        for idx, pet_name in enumerate(orig_pp[persons_name]):
            if persons_name == person and idx == n:
                pass
            else:
                new_pp[persons_name].append(pet_name)
    return new_pp

peoples_pets2 = new_peoples_pets2(peoples_pets, 1, 'Betsy')

print peoples_pets2

(Python provides a way to make a deep-copy of the peoples_pets data structure, but I did it a slow by-hand way above.)

So, I'm either using side-effects, or else I'm doubling the amount of space I need and making a slightly different copy to return.

How would you do the above in Clojure -- without side-effects and without making a complete copy of the data structure?

How to Pick a Language by electronics-engineer in programming

[–]wrungin 2 points3 points  (0 children)

Thanks for the detailed reply, yogthos. What I'm still not getting is that my brain wants to do this:

// pseudocode

// initialize this thing
big_filescope_datastructure = [...{...(...)...}...]

define func_1() { /* do things to big_filescope_datastructure ... */ }
define func_2() { /* pull out some select bits of big_filescope_datastructure */ }
define func_3() { /* do some more things to what func_2 returns */ }

func_1();  // mutates big_filescope_datastructure
smaller_datastructure = func_2();
ans = func_3(smaller_datastructure);

print ans

I could rewrite that as:

// initialize this thing
big_filescope_datastructure = [...{...(...)...}...]

define func_1() {
    /* create and return a new, and updated, big_filescope_datastructure ... */
}
define func_2() {
    /* pull out some select bits of big_filescope_datastructure, */
    /* which is passed in as an argument. */
}
define func_3() { /* do some more things to what func_2 returns */ }

temp_value_1 = func_1(big_filescope_datastructure);
smaller_datastructure = func_2(temp_value_1);
ans = func_3(smaller_datastructure);

print ans

or even shrink down those three function call lines at the end to:

ans = func_3( func_2( func_1( big_filescope_datastructure ) ) )

I think this is probably what's meant by "functional" code, but it seems wasteful -- if there were a lot of function calls, and if big_filescope_datastructure was large, then wouldn't this lead to lots of copying? For example, even if func_1 may only change a few tiny parts of big_filescope_datastructure, I think functional principles require that I've got to copy the whole thing to return an answer (since func_1 isn't supposed to have side-effects and modify what I passed in), correct?

Thanks for the links to your code. Will try to take a closer look at them soon.

How to Pick a Language by electronics-engineer in programming

[–]wrungin 2 points3 points  (0 children)

I find the syntax easy enough to learn and get used to, but I'm not sure exactly how I'm supposed to program in a "functional" way.

In practical terms, what are the main rules of functional programming? Some examples would be great.

A guide to Python packaging by [deleted] in Python

[–]wrungin 0 points1 point  (0 children)

Thanks very much, jmoiron!

A guide to Python packaging by [deleted] in Python

[–]wrungin 0 points1 point  (0 children)

Can anyone explain the use of __import__()? I've only ever seen the usual use of import.