Open Side Menu Go to the Top

03-10-2016 , 02:13 PM
I see now. thanks!
Programming homework and newbie help thread Quote
Programming homework and newbie help thread
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
Programming homework and newbie help thread
03-10-2016 , 03:52 PM
Quote:
Originally Posted by gaming_mouse
in the first version, there is a statement that *may* get executed depending on the the value of some other variable. in the second, an expression that is always executed.
The first version seems like a weird way to structure code anyway. Wouldn't you rather write it as

Code:
if (stateIsEvil)
    myStyle = "functional";
else
    myStyle = "imperative";
And isn't this equivalent to the second version of your code?

Quote:
Originally Posted by gaming_mouse
the difference would be clearer written like this:
Code:
myStyle = programmerStyle(stateIsEvil)
that is, we're setting the value of myStyle to the result of a function, and that result (assuming the function is pure) depends only on the value of stateIsEvil.

the difference is extremely subtle and unimportant in such a trivial example, but as the number of things that style depends on grows, and the complexity of the logic expands, the functional code will remain clear, while the imperative code becomes impossible to reason about.
The difference in how the code is set up is clearer here, but inside that programmerStyle() function you still need to have some code similar to our above examples.
Is this difference you talk about only in regards to how the code looks, ie readability and "clearness" of the code, but no difference in actual functionality?
What do you mean that the imperative code will become impossible to reason about?
And what is the difference between functional code and imperative code?
Programming homework and newbie help thread Quote
03-14-2016 , 07:28 PM
gaming_mouse - I started reading Out of the Tar Pit not really expecting an academic paper, made it about 20 pages before I started falling asleep. One thing I'm kind of curious about as you get away from the basic tenets illustrated in your examples above or from the academic discussion of "accidental state" at the beginning of the paper, and into more real world examples: how do you build large, complex systems without accruing large, complex state along the way?

(if there's a particular part of the paper that talks about this I'll check it out)
Programming homework and newbie help thread Quote
03-14-2016 , 09:03 PM
"The only thing a stateless program is good for is heating up your machine."

The central tenet of Functional Programming is NOT to remove state entirely from the system. In fact, FP does embrace state, but minimizes the global state of the system to, preferably, one function, and defining every other function so that one input is guaranteed to resolve to one output each time. This would be analogous to writing a game where only the game loop presents state.

Contrary to popular opinion, one of the central tenets of JAVA was to minimize state, through isolation. It isn't by accident that primitives are immutable.

http://www.artima.com/intv/gosling313.html

FP, at it's birth, was a response to handling transactional state, ie, if you look at the current state of a series of bank transactions, are you guaranteed to get an accurate result at 5:39pm vis-a-vis OO and FP? Unfortunately, FP fails at this, and this still stands as one of the great unsolved computer problems.
Programming homework and newbie help thread Quote
03-14-2016 , 10:32 PM
Quote:
Originally Posted by goofyballer
gaming_mouse - I started reading Out of the Tar Pit not really expecting an academic paper, made it about 20 pages before I started falling asleep. One thing I'm kind of curious about as you get away from the basic tenets illustrated in your examples above or from the academic discussion of "accidental state" at the beginning of the paper, and into more real world examples: how do you build large, complex systems without accruing large, complex state along the way?

(if there's a particular part of the paper that talks about this I'll check it out)
ha, i found the writing fascinating and pretty accessible, but yeah, i should have warned you that it wasn't light reading. the good news is that i think the first 20-30 pages give you the key ideas.

your other question is really tough to answer. basically, in my experience, you just have to take small lessons and keep applying them and expanding your knowledge, and getting help from people with more experience. but keeping state, and the different kinds of state, separated in large systems... well, that's kind of the million dollar question. i still deal with it on a daily basis. if you're really serious about it, probably the most practical advice is to work in a functional language that has a good community (haskell, clojure, etc), and then spam their irc / SO / programmers.SE with questions as you learn.

if you have specific questions about a JS or ruby project, I can try to help you here, but, just as a random example, if you were to say, "dude, how do i do this **** in C#?" my answer would be, "i don't know, and it would take me a lot of research to find out, and even then it would probably be fighting the tide."
Programming homework and newbie help thread Quote
03-15-2016 , 02:51 AM
I started writing a post with a thesis of "well, you CAN do functional-ish stuff in languages that have some base level of support for functional features, right?", because I mean C++ has lambdas which are basically the greatest thing since sliced bread, and so I set out to write a C++ version of my JS example from above:

Code:
void traverse(Node* root, std::function<void(Node*)> callback) {
  std::vector<Node*> array;
  std::function<std::vector<Node*>(Node*)> recur;
  recur = [&recur] (Node* node) -> std::vector<Node*> {
    if (node == nullptr) return {};
    else {
      std::vector<Node*> array{recur(node->left)};
      auto rightResult = recur(node->right);
      array.insert(array.end(), rightResult.begin(), rightResult.end());
      array.push_back(node);
      return array;
    }
  };
  auto array = recur(root);
  for (Node* n : array) {
    callback(n);
  }
}
What a crime against humanity. It's worth noting though that if std::vector implemented the + operator to allow concatenation, that abortion in the middle could look a lot simpler (maybe even one line like the JS example), so some of that grossness isn't because of the language but rather because of the standard library.

I dunno, I guess I was hoping there are general strategies you can apply to OO languages that draw from FP theory to make larger systems more simple - like, the basic idea of "avoid mutable state, use more pure functions" isn't so hard. But I guess without diving fully into functional languages like you suggested I can't really be sure how much that theory is/isn't dependent on the nature and use of functional languages themselves. I dunno if it's "cheating" to want the end without the means but doing some particularly painful code refactors on an aging codebase at work over the last week I'm definitely interested in strategies for simplifying things from the beginning.
Programming homework and newbie help thread Quote
03-15-2016 , 09:35 AM
Quote:
Originally Posted by goofyballer
I started writing a post with a thesis of "well, you CAN do functional-ish stuff in languages that have some base level of support for functional features, right?", because I mean C++ has lambdas which are basically the greatest thing since sliced bread, and so I set out to write a C++ version of my JS example from above:

Code:
void traverse(Node* root, std::function<void(Node*)> callback) {
  std::vector<Node*> array;
  std::function<std::vector<Node*>(Node*)> recur;
  recur = [&recur] (Node* node) -> std::vector<Node*> {
    if (node == nullptr) return {};
    else {
      std::vector<Node*> array{recur(node->left)};
      auto rightResult = recur(node->right);
      array.insert(array.end(), rightResult.begin(), rightResult.end());
      array.push_back(node);
      return array;
    }
  };
  auto array = recur(root);
  for (Node* n : array) {
    callback(n);
  }
}
What a crime against humanity. It's worth noting though that if std::vector implemented the + operator to allow concatenation, that abortion in the middle could look a lot simpler (maybe even one line like the JS example), so some of that grossness isn't because of the language but rather because of the standard library.

I dunno, I guess I was hoping there are general strategies you can apply to OO languages that draw from FP theory to make larger systems more simple - like, the basic idea of "avoid mutable state, use more pure functions" isn't so hard. But I guess without diving fully into functional languages like you suggested I can't really be sure how much that theory is/isn't dependent on the nature and use of functional languages themselves. I dunno if it's "cheating" to want the end without the means but doing some particularly painful code refactors on an aging codebase at work over the last week I'm definitely interested in strategies for simplifying things from the beginning.
you absolutely can borrow concepts in OO, I didn't mean to imply it was all or nothing. I thought you were asking something else.

The TLDR version is: use value objects wherever possible, and replace mutator methods with methods that return a new value object.

That said, C++ is just gonna be tough going. The problem is that the whole point, really, of functional programming is to allow you to write declarative code and avoid low-level details, whereas C++ is a low-level language that forces you always to consider them.
Programming homework and newbie help thread Quote
03-15-2016 , 09:53 AM
Goofyballer, the entire idea is this:

Code:
traverse_tree(tree_a)
will always resolve to the same answer. If at anytime you are calling this function with tree_a and getting a different answer, you are breaking FP.

If you are changing tree_a, you should, via, FP, be creating a copy of tree_a into whatever is changed into tree_b. The idea is to record your history and see "time" like a film as opposed to destructive, thus tree_a is "stateless" but the system, when combined with tree_a, tree_b, etc, has a sense of time. I guess you can compare the idea to git, where each change is stored somewhere in history and nothing is erased.

The one-liners, lambdas, etc, are all semantic issues that aren't a part of the FP cannon, no more than inheritance and polymorphism are exclusive to OO. The ideas cross-pollinate.
Programming homework and newbie help thread Quote
03-15-2016 , 11:08 AM
Quote:
Originally Posted by goofyballer
I started writing a post with a thesis of "well, you CAN do functional-ish stuff in languages that have some base level of support for functional features, right?", because I mean C++ has lambdas which are basically the greatest thing since sliced bread, and so I set out to write a C++ version of my JS example from above:

Code:
void traverse(Node* root, std::function<void(Node*)> callback) {
  std::vector<Node*> array;
  std::function<std::vector<Node*>(Node*)> recur;
  recur = [&recur] (Node* node) -> std::vector<Node*> {
    if (node == nullptr) return {};
    else {
      std::vector<Node*> array{recur(node->left)};
      auto rightResult = recur(node->right);
      array.insert(array.end(), rightResult.begin(), rightResult.end());
      array.push_back(node);
      return array;
    }
  };
  auto array = recur(root);
  for (Node* n : array) {
    callback(n);
  }
}
What a crime against humanity. It's worth noting though that if std::vector implemented the + operator to allow concatenation, that abortion in the middle could look a lot simpler (maybe even one line like the JS example), so some of that grossness isn't because of the language but rather because of the standard library.

I dunno, I guess I was hoping there are general strategies you can apply to OO languages that draw from FP theory to make larger systems more simple - like, the basic idea of "avoid mutable state, use more pure functions" isn't so hard. But I guess without diving fully into functional languages like you suggested I can't really be sure how much that theory is/isn't dependent on the nature and use of functional languages themselves. I dunno if it's "cheating" to want the end without the means but doing some particularly painful code refactors on an aging codebase at work over the last week I'm definitely interested in strategies for simplifying things from the beginning.
Interesting. To make a long story short, a different, more traditional way in C++ would be to use composition to define the way the tree is traversed. I played around with implementing a template for traversing the tree. You can do that and the code actually ends up being simple to traverse the tree. However, one would have to look in a few other code segments to examine the different traversal ways. The advantage to the approach you took above would be that all of the logic is in one place more or less thus no need to look in other modules/files. The lambda function placed in the middle there seems ok to me from a readability, program maintenance point of view FWIW. Am I getting the basic gist of the advantages of functional programming?

I agree with GM and DaveT that your code above is more about the inherent nature of C++.
Programming homework and newbie help thread Quote
03-15-2016 , 01:07 PM
Coupling between the type of tree traversal and the templates may be undesirable. Just an alternative not necessarily a better one. Separate declarations for the enumerated type, the template class and function template in lieu of everything declared in one function template has its drawbacks I guess.


Main
Code:
#include "TreeTraversal.h"
struct NodeStruct;
 
typedef struct NodeStruct
{
       int   value;
 
       struct NodeStruct * next;
}
NODE_STRUCT;
 
 
int main()
{
       NODE_STRUCT root;
 
       TreeTraversal::TraverseTree<NODE_STRUCT, TreeTraversal::TraversalOrder>
                              (&root, TreeTraversal::TRAVERSAL_ORDERS::IN_ORDER);
    return 0;
}
.h file

Code:
include <vector>
 
 
namespace TreeTraversal {
 
       typedef enum class TraversalOrders {
              IN_ORDER,
              POST_ORDER,
              PRE_ORDER
       } TRAVERSAL_ORDERS;
 
       template <typename Node>
       class TraversalOrder {
       public:
              TraversalOrder(TRAVERSAL_ORDERS to) : _to(to) {}
              std::vector<Node *> recur(Node * node) {
                     std::vector <Node *> array;
 
                     return array;
 
              }
 
              void callback(Node *) {
 
              }
       private:
              TRAVERSAL_ORDERS _to;
              TraversalOrder() = delete;
       };
 
       template < typename Node,
                     template <typename Node> class TraversalOrder >
       void TraverseTree(Node * root, TRAVERSAL_ORDERS to) {
 
              TraversalOrder<Node> traverseTheTree(to);
 
              auto array = traverseTheTree.recur(root);
 
              for (Node * n : array) {
                     traverseTheTree.callback(n);
              }
       }
 
}

Last edited by adios; 03-15-2016 at 01:14 PM.
Programming homework and newbie help thread Quote
03-15-2016 , 05:47 PM
Quote:
Originally Posted by adios
Interesting. To make a long story short, a different, more traditional way in C++ would be to use composition to define the way the tree is traversed. I played around with implementing a template for traversing the tree. You can do that and the code actually ends up being simple to traverse the tree. However, one would have to look in a few other code segments to examine the different traversal ways. The advantage to the approach you took above would be that all of the logic is in one place more or less thus no need to look in other modules/files. The lambda function placed in the middle there seems ok to me from a readability, program maintenance point of view FWIW. Am I getting the basic gist of the advantages of functional programming?
I can't really read C++ too well, but in general, you don't use objects or mutation in your functions either, which I think is happening on the array. If there was a way, you'd recur so that you are passing in the array as an argument to the inner function so you would have a non-mutating array, or rather, film-like time-capsule of each copy of the array and simply return the final value (or whole stream of values, which ever you need). Sort of hand-wavy, but that's how it is supposed to work.

Also, you shouldn't be afraid to have multiple functions in your program. In fact, you should prefer having a function for each different action you are doing. The array.insert and array.push methods could be pulled out into their own functions, for example..
Programming homework and newbie help thread Quote
03-15-2016 , 06:24 PM
+1 to daveT's recent comments in this thread.

Clojure has treated you well...
Programming homework and newbie help thread Quote
03-16-2016 , 02:55 PM
I consider learning Clojure by biggest mistake.

At least for web-building, creating a site that is 99% immutable is pretty straightforward (not sure about JS here). The mutation can be isolated to the session handling and the database.

I'd have to say other things aren't so simple. The poker bot was pretty difficult and kind of wonky for straight FP. It can be done, but oddly, it gets very difficult to logic about and even more difficult to debug. I ripped out some of the FP and shifted it over the mutatable, but even so, the immutable -vs- mutable was hand-wavy, IMO, and didn't make much difference either way, except that the mutable stuff was isolated to a very small part of the program.
Programming homework and newbie help thread Quote
03-16-2016 , 04:27 PM
That's surprising. Poker bot logic should be a perfect fit for FP. You have a game state (cards, action history, board cards), and potentially an opponent model as input, and the output is another action.

Maybe you just didn't find the right design?
Programming homework and newbie help thread Quote
03-16-2016 , 05:18 PM
I reviewed my approach with a foremost Clojure expert and he told me to use some strategy to follow FP correctly, and it matched my code pretty much exactly, so I feel like I can talk about why I didn't like the approach (argumentum ad verecundiam)

basically, the problem boiled down to keeping track of "state" in a single game loop, which would take arguments for:

player
bot
player-hand
bot-hand
board
deck
player-turn
street
pot-size
player-money
bot-money
bet-size
action
etc.

whether you used all of this in a map or not was irrelevant, and using a map starts to look very much like an object, so let's dismiss that.

As you can begin to see, the chaining of all the cases combined with further cases, regardless of using multi-methods or not, starts to get very complex, and it would be more practical to remove that movement from a function and use atoms (analogous to structs) instead. It is also much easier to set some starting state using atoms instead of function calls.

Even so, you need some other functions to react to the play, you end up with a bunch of (+ var 1) as return and recurring values, which basically creates stateful change. When you return a value from a function, it ends up altering the global state of the game (this is the accidental mutation state).

It was hard to justify the differences, where the only difference was using recurrences as opposed to atomic changes. In simple terms, making it more OO-flavored greatly simplified the logic. This isn't to say that I totally removed the FP-style calls to the game loop. I ended up with a hybrid approach, using atoms to track the game state, which helped to clarify the changes inside of the functions and the game loop, via using some global state instead of a series of functions that took and returned arguments. As you can imagine, if one function call returns something wrong, it is very difficult to trace exactly which function caused that error to occur, since you not only have to track the game loop, but the myriad other functions that interact with each turn.

The FP was relegated to saying "next turn" and evaluating hand-strengths. The rest of the mutating stuff (and you can't argue that there was no mutation as it was simply obscured in functions) was put into the atoms.

Think of a system where each function takes 3+ arguments and returns 3+ possible, but not always, changing values. Conceptually, it using FP- or OO- flavored "state" makes no difference, but practically, there's a large difference. Even visually, it is much easier to look at atomic changes over functional returns.

Think of it like this. You have a function that takes the changing board as an argument. If it is preflop, you return a list of 3 cards, the flop, you return a list of 4 cards. If it is the turn, return a list of 5 cards, else, return show hands. There really is no difference between altering an atom or returning the list as it is mutation either way you slice it. Of course, many functions end up depending on other functions, like what happens when someone is all-in, etc. At that level of changing state, the complexity of FP just got too large and didn't make much sense to be "pure."
Programming homework and newbie help thread Quote
03-18-2016 , 11:20 AM
Quote:
Originally Posted by daveT
"The only thing a stateless program is good for is heating up your machine."
"I love stateless programming!"

"Doesn't it have some disadvantages?"

"Doesn't what have some disadvatanges?"
Programming homework and newbie help thread Quote
03-21-2016 , 07:47 PM
With regards to website obesity, optimal performance, data usage etc, what is the professional standard using Bootstrap, if you have a row of images with text below them that ranges from 2 images displayed in the row for mobile devices, then to 3, 4 and then finally 6 images displayed for your max desktop width, is it considered better practice to be saving multiple sizes of each image or to just have one image set to responsive?
Programming homework and newbie help thread Quote
03-23-2016 , 05:43 AM
re: discussion of state and complexity from earlier, had a nice example of it tonight working on the PredictIt market tracker thing I was posting about in the other thread.

The page has nested controllers - there's one main controller that displays all the markets, and individual child controllers for each contract in a market. I was initializing each child controller with two copies of its contract - the earliest copy the server knew about, and the newest copy, and the child controller could then say how much it's gone up/down in that timeframe.

I then wanted to have a button next to each market (parent controller) that would "reset" its change tracking, so I could be like yeah, I get it, this market had a 10 point swing, I don't want my vision cluttered with that anymore. The problem was, the reset button updates my main data model to copy the newest data for a market over the old baseline version...but the child controllers for each contract had already cached a copy of the old contract, so they didn't update, because from their view nothing had changed. I kept thinking, how do I propagate the data change from the model to the client?

Then I realized I could just...not keep the cached state in the child controller at all, and get it from the data model when I needed to use it. And then everything worked. Huh, how about that.

(still feels kinda ugly writing code that's doing so much work in what feels like an accessor function, since it has to search through like two things to find the right element every time you just want to know how much something changed, but I guess that's my C++ nature resisting change)
Programming homework and newbie help thread Quote
03-23-2016 , 05:45 AM
Yeah, avoid "scope soup". Your data should be encapsulated in services.
Programming homework and newbie help thread Quote
03-23-2016 , 04:13 PM
Yeah, in the course of googling answers to things and reading lots of articles and stuff trying to figure out best practices, I came across this that talked about scope soup. It advocates using OOP-style classes for your controllers that avoid use of scope, so I started there (keeping my state in controllers) before finding another article, I think this one, talking about putting data in a service and isolating your controllers from it as much as possible.

It's really hard as someone new to Angular to figure out the right way to do things when soooooo many answers on SO or wherever talk about using $scope but most articles I read are like "no, definitely don't do that if you don't have to".
Programming homework and newbie help thread Quote
03-23-2016 , 04:46 PM
fwiw, the kind of thing you're discussing (and just the complexity in general of angular) is why i ended up moving away from it.
Programming homework and newbie help thread Quote
03-23-2016 , 08:35 PM
Angular 2 is simplified, from what I understand you just have directives and services, controllers no longer exist. I haven't done any Angular 2 yet but will be jumping in pretty soon.
Programming homework and newbie help thread Quote
03-23-2016 , 09:11 PM
Quote:
Originally Posted by ChrisV
Angular 2 is simplified, from what I understand you just have directives and services, controllers no longer exist. I haven't done any Angular 2 yet but will be jumping in pretty soon.
what about scopes, transclusions, eval, $eval, template compiling, the redraw loop -- ah, the memories!
Programming homework and newbie help thread Quote
03-23-2016 , 10:08 PM
Quote:
Originally Posted by gaming_mouse
what about scopes, transclusions, eval, $eval, template compiling, the redraw loop -- ah, the memories!
Not sure, I'll let you know after I learn it
Programming homework and newbie help thread Quote
03-28-2016 , 03:25 PM
Hey, just looking for some quick feedback on a pretty simple problem I encountered while going through an online book for an into to programming class I'm taking. EDIT this is python BTW, if that isn't clear.

I don't need help with getting the right answer here. I'm just curious if I'm doing things in a "good way." The book makes you pass tests but, if you get the correct output, you get no feedback on how (in?)elegant your solution is. So here it is.

PROBLEM:
Write a loop to print all elements in hourly_temperature. Separate elements with a -> surrounded by spaces. Sample output for the given program:
90 -> 92 -> 94 -> 95

MY CODE:
hourly_temperature = [90, 92, 94, 95]
i = 0

for temp in hourly_temperature:
if i != (len(hourly_temperature) - 1):
print(hourly_temperature[i], '-> ', end='')
i = i + 1
else:
print(hourly_temperature[i], '', end='')



print('') # print newline

(FYI both the first and last lines of code (that create the list and print a new line at the end) are in the program automatically and can't be removed or changed.)

Thanks for any input!
Programming homework and newbie help thread Quote
Programming homework and newbie help thread
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
Programming homework and newbie help thread

      
m