Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Mon Jul 30, 2012 4:55 pm UTC

I love this paradigm

Code: Select all

typedef std::function<void()> niladic;
class Resource {
    niladic destructor;
public:
    Resource() : destructor([]{}) {}
    Resource(niladic destructor) : destructor(destructor) {}
    ~Resource() { destructor(); }
   
    Resource(const Resource& res) = delete;
    Resource& operator=(const Resource& res) = delete;
   
    Resource(Resource&& res) : destructor(res.destructor) {
        res.destructor = []{};
    }
    Resource& operator=(Resource&& res) {
        destructor();
        destructor = res.destructor;
        res.destructor = []{};
        return *this;
    }
};

template<typename T>
class LeaseSet : public std::set<T> {
public:
   // ...
    Resource insert(const T& value) {
        std::set<T>::insert(value);
        auto remover = [=] {
            erase(value);
        };
        return Resource(remover);
    }
};


Means you can

Code: Select all

LeaseSet<int> foo;
Resource a = foo.insert(5);
{
Resource b = foo.insert(6);
}
for(int i : foo) { cout << i << endl; } // prints 5


Which is so awesome when it comes to managing subscriptions.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11129
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Jul 30, 2012 6:49 pm UTC

You, sir, name? -- yes, RAII lambda destructors rock.

I'd be tempted to call the Resource class "call on exit scope". Less abstract, but more self documenting.
tastelikecoke wrote:I got lost there. Do you mean importing C++ code into C or is that supposed to be C source file? I don't know if I can use the standard library that liberally on our assignment.

Well, I was talking about solving the problem, not solving your assignment. :) I was saying that a nice way to handle needing a stable sort in C would be to use C++ std::stable_sort, and exploit the ability for C++ to export a C-compatible library.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Mon Jul 30, 2012 6:55 pm UTC

Yakk wrote:
tastelikecoke wrote:I got lost there. Do you mean importing C++ code into C or is that supposed to be C source file? I don't know if I can use the standard library that liberally on our assignment.

Well, I was talking about solving the problem, not solving your assignment. :) I was saying that a nice way to handle needing a stable sort in C would be to use C++ std::stable_sort, and exploit the ability for C++ to export a C-compatible library.


If solving the problem is the object, C89 and later has solved it for you:

Code: Select all

/* in stdlib.h */
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));


Yakk wrote:You, sir, name? -- yes, RAII lambda destructors rock.

I'd be tempted to call the Resource class "call on exit scope". Less abstract, but more self documenting.


I copied it from a codebase where the name actually makes sense.

But yeah, that, along with the below has added a whole new level of awesome to my C++ code.

Code: Select all

template<typename... T>
class Event {
  unsigned long idx;
  std::map<idx, std::function<void(T...)>> callbacks;
public:
  Event() : idx(0) {}
  void invoke(T... args) {
     for(auto callback : callbacks) callback(args...);
  }
  Resource listen(const std::function<void(T...)>& callback) {
     unsigned long i = idx++;
     callbacks[i] = callback;
     return Resource([this, i] { callbacks.erase(i); });
   }
};


(typed from memory, may or may not compile).
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11129
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Jul 30, 2012 7:26 pm UTC

You, sir, name? wrote:
Yakk wrote:
tastelikecoke wrote:I got lost there. Do you mean importing C++ code into C or is that supposed to be C source file? I don't know if I can use the standard library that liberally on our assignment.

Well, I was talking about solving the problem, not solving your assignment. :) I was saying that a nice way to handle needing a stable sort in C would be to use C++ std::stable_sort, and exploit the ability for C++ to export a C-compatible library.


If solving the problem is the object, C89 and later has solved it for you:

Code: Select all

/* in stdlib.h */
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
qsort is not stable.

So now you have to repack the array with indexes (or initial pointer values) for each element, sort that, then strip out the index information, and return that.
Yakk wrote:You, sir, name? -- yes, RAII lambda destructors rock.

I'd be tempted to call the Resource class "call on exit scope". Less abstract, but more self documenting.


I copied it from a codebase where the name actually makes sense.

But yeah, that, along with the below has added a whole new level of awesome to my C++ code.

[SNIP event-listener implantation]

Bad programmer, no cookie.

At 100 listeners installed per frame, 60 frames per second, that fails after 8 and a bit days. In a less ridiculous situation, it still fails after a few weeks/months/years.

Use a 64 bit index, and put off your crash for eons. :) Or, make it a std::set< std::function<void(T...)>* >, and use new to get unique keys. Or write your own pseudo-heap of unique keys that deals with recycled keys (store recycled keys somewhere, and use them first...)

Another problem is that resource destruction in response to a callback could cause problems in the for loop. This one is serious: fixing it requires some work on the part of invoke.

(I mention these because I've implemented isomorphic code to yours, and these issues actually came up...)
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Mon Jul 30, 2012 7:59 pm UTC

Yakk wrote:Bad programmer, no cookie.

At 100 listeners installed per frame, 60 frames per second, that fails after 8 and a bit days. In a less ridiculous situation, it still fails after a few weeks/months/years.

Use a 64 bit index, and put off your crash for eons. :) Or, make it a std::set< std::function<void(T...)>* >, and use new to get unique keys. Or write your own pseudo-heap of unique keys that deals with recycled keys (store recycled keys somewhere, and use them first...)


As I said, this code is from memory. Don't nitpick on the details. It is going to have errors.

Yakk wrote:Another problem is that resource destruction in response to a callback could cause problems in the for loop. This one is serious: fixing it requires some work on the part of invoke.

(I mention these because I've implemented isomorphic code to yours, and these issues actually came up...)


Yeah. I've had that happen too. In my case, I worked around the problem because I couldn't afford the performance hit of solving it, but my ansatz for solving the problem would look something like this:

Code: Select all

template<typename... T>
class Event {
  unsigned long idx;
  std::map<idx, std::shared_ptr<std::function<void(T...)>>> callbacks;
public:
  Event() : idx(0) {}
  void invoke(T... args) {
     for(std::shared_ptr<std::function<void(T...)>> callback : callbacks) {
       auto callbackptr = callback.get();
       (*callbackptr)(args...);
     }
  }
  Resource listen(const std::function<void(T...)>& callback) {
     unsigned long i = idx++;
     callbacks[i] = std::shared_ptr<std::function<void(T...)>>(new std::function<void(T...)>(callback));
     return Resource([this, i] { callbacks.erase(i); });
   }
};


Again, completely untested code. But you get the idea.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Mon Jul 30, 2012 10:23 pm UTC

In C++ (allowing many C++11 features but not even all that are supported by recent GCCs), is there a way to inhibit conversions of parameters? Something like explicit on non-constructors?

Code: Select all

struct Foo{
    explicit void foo(std::string const & s) {} // illegal: explicit can only be used on constructors
};

Foo f;
f.foo("abc"); // bad; needs conversion
f.foo(std::string("abc")); // ok


Edit, ooo, I bet I could do something like this...

Code: Select all

template<typename T> struct holder {
    T const & val;
    holder(T const & v) : val(v) {}
};

struct Foo {
    void foo(holder<std::string> s) {}
};

but it probably isn't worth it. :-)

User avatar
Yakk
Poster with most posts but no title.
Posts: 11129
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Jul 30, 2012 10:49 pm UTC

Sure, using SFINAE:

Code: Select all

template<typename T, typename U>
struct type_equals { enum {value = false}; };
template<typename T>
struct type_equals<T,T> { enum {value = true}; };

template<typename T>
void foo(T const& s, std::enable_if<type_equals<T, std::string>::value>::type* unused = nullptr)
{
  // do stuff
}

Anything other than a std::string will not hit this override, unless I screwed up. enable_if is C++11 I think, but easy to write:

Code: Select all

template<bool test, typename T=void>
struct enable_if {};
template<typename T>
struct enable_if<true, T> { typedef T type; }

This might not work (is does that type_equals partial specialization above work?), but the strategy will.

If you don't like the default parameter trick, in C++0x you can do this:

Code: Select all

template<typename T>
auto foo( T const& s ) -> std::enable_if< type_equals< T, std::string > >::type

and you can rename T to be "std_string_only" or something of the sort.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
hotaru
Posts: 1045
Joined: Fri Apr 13, 2007 6:54 pm UTC

Re: Coding: Fleeting Thoughts

Postby hotaru » Tue Jul 31, 2012 12:09 am UTC

Yakk wrote:
You, sir, name? wrote:
Yakk wrote:
tastelikecoke wrote:I got lost there. Do you mean importing C++ code into C or is that supposed to be C source file? I don't know if I can use the standard library that liberally on our assignment.

Well, I was talking about solving the problem, not solving your assignment. :) I was saying that a nice way to handle needing a stable sort in C would be to use C++ std::stable_sort, and exploit the ability for C++ to export a C-compatible library.


If solving the problem is the object, C89 and later has solved it for you:

Code: Select all

/* in stdlib.h */
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
qsort is not stable.

the standard doesn't say anything that would prevent qsort from using a stable sort, but
the GLIBC manual wrote:If you want the effect of a stable sort, you can get this result by writing the comparison function so that, lacking other reason distinguish between two elements, it compares them by their addresses. Note that doing this may make the sorting algorithm less efficient, so do it only if necessary.

Code: Select all

factorial product enumFromTo 1
isPrime n 
factorial (1) `mod== 1

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Coding: Fleeting Thoughts

Postby PM 2Ring » Tue Jul 31, 2012 3:56 am UTC

Ben-oni wrote:
PM 2Ring wrote:I'm currently writing a Haskell program to calculate e to arbitrary precision. I've just got it working correctly, but I'm sure it's rather inefficient. In an imperative language, I'd print each block of digits as I generate them, but I don't know how to do that sort of thing in Haskell, so I'm just collecting all the digits into a list & printing them out at the end.

The easy way, I think, would be to calculate e as a Rational and then print the Rational. I can get the first thousand digits in a few seconds, but it's hardly efficient (10000 decimal places takes several minutes). But now I have more e than I'll ever need.

If you have an incremental solution, would mind sharing your code?


I guess you multiply the Rational by a large power of 10 to convert it to decimal? I was doing that sort of thing the other day when calculating square roots by continued fractions and by Newton's method.

Here's my e code, in Haskell, Python, and C. The algorithm works by converting the factorial base representation of e to decimal, inspired by a program written by Dik T. Winter, but optimised by using the inverse function of log10(n!) to determine how many terms of the series are required for each loop.

The Haskell version is very much a work in progress, I intend to improve it as my Haskell skills grow. The Python version is a fairly direct translation of the C version which I wrote when I was first learning Python. I'm quite fond of this algorithm, and I like to implement it when I'm first learning a new language. I even have a PostScript version lurking somewhere in my archives.

Code: Select all

-- Haskell. Compute e using factorial base notation. PM 2Ring, 2012.07.30

{-
The number is stored as a list of pairs (index, value), with the first index in the list being 2.
The list represents a sum of value/(index !)
When the number is normalized, 0 <= value < index.

In this format, e = 2.1111...

To produce the decimal digits, the number is repeatedly multiplied by a power of 10, normalized,
and the portion preceding the "decimal" point is printed.
This process is very similar to the usual algorithm for converting a non-base 10 number to decimal.
-}

blocklen = 4
blockmult = 10 ^ blocklen

--normalize a list in factorial base notation.
normalize :: [(Int, Int)] -> Int -> ([(Int, Int)], Int)
normalize [] a = ([], a)
normalize (x:xs) a = (y:ys, c)
    where (ys, b) = normalize (xs) a
          (y, c) = normcell x b
         
--normalize a single cell of a list in factorial base notation.
--normcell :: (Integral a) => (a, a) -> a -> ((a, a), a)
normcell :: (Int, Int) -> Int -> ((Int, Int), Int)
normcell (i, v) a = let (q,r) = (a + v) `divMod` i in ((i, r), q)

--multiply the values in all cells by blocksize, effectively shifting the number in the list
lshift :: [(t, Int)] -> [(t, Int)]
lshift = map (\(u, v) -> (u, v * blockmult))

--call function f n times. 
loop :: Int -> (a -> a) -> a -> a
-- loop 1 f = f
-- loop n f = f . loop (n-1) f
loop n f = foldr (.) id (replicate n f)

--zero-pad a numeric string on the left to the desired width
zpad :: Int -> [Char] -> [Char]
--zpad n s = replicate (max 0 (n - length s)) '0' ++ s
zpad width numstr = if length numstr < width then '0':(zpad (width - 1) numstr) else numstr

--convert a number to string and zero-pad it.
showp :: Int -> [Char]
showp n = zpad blocklen $ show n


--package it all into a form suitable for repeated function invocation,
--i.e., put the input into a tuple of the same format as the output tuple
process :: ([(Int, Int)], [Int]) -> ([(Int, Int)], [Int])
process (q, digits) =
    let (q1, d1) = normalize (lshift q) 0
    in (q1, digits ++ [d1]) 


--initialize the list with the factorial-base expansion of e - 2
q0 = zip [2..70] $ repeat 1

--Do it!
(_, dlist) = loop 25 process (q0, [])

--and print!
main = putStrLn $ '2':'.': (concat $ map showp dlist)


Code: Select all

#! /usr/bin/env python

"""
    ECalc - Big e calculator

    Generate digits of e, using factorial base notation
    Inspired by Dik T. Winter

    Created by PM 2Ring 2003.12.26
    Converted from C to Python 2007.12.10
"""

import sys, math

#Global constants
N = 50                            #Default number of digits
W = 5                             #Digits per block
A = 10 ** W
LR2P = .5 * math.log(2.*math.pi)  #Log Root 2 Pi
L10 = math.log(10.)               #Log 10

def invlfact(n):
    """ Inverse Stirling's approx for log n factorial, using Newton's method """
    x = y = n * L10 - LR2P
    for i in xrange(3):
        x = (y + x) / math.log(x)
    return int(round(x))

def bigE(n):
    """ Generate n digits of e using factorial base notation """
    kmax = invlfact(n) + 1
    print "Calculating e to %d places, using %d cells" % (n, kmax)

    #Table for factorial base digits, initialized with series for e-2 = 1/2! + 1/3! + ...
    #We ignore first two entries
    d = [1] * kmax
    print "e ~= 2."

    j = 1
    while n>0:
        # Get the next W digits by firstly multiplying d by A,
        # propagating carries back down the array,
        # then printing the integer part & removing it.
        kmax = invlfact(n)    #Number of cells needed for this loop
        c = 0                 #Clear carry
        for k in xrange(kmax, 1, -1):
            d[k] = d[k] * A + c
            c = d[k] // k
            d[k] -=  c*k

        #Print block & field separator. May need modifying if you make W large
        jj = (j%10 and 1  or  j%50 and 2  or  j%200 and 3  or  4) - 1
        print "%0*d%s" % (W, c, "\n" * jj),

        j += 1; n -= W

def main():
    #Get number of digits
    n = len(sys.argv) > 1 and int(sys.argv[1]) or N
    bigE(n)

if __name__ == '__main__':
    main() 


Code: Select all

/*
 *  E
 *
 *  Generate digits of e using factorial base notation
 *  Inspired by Dik T. Winter
 *
 *
 *  Dec 26 2003
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define N 50
#define W 5
#define A 100000

/* log10 inverse factorial */
long invlfact(long n);

static double LR2P, L10;

int main(int argc, char *argv[])
{
    long n=0, k, kmax, *d, c, j;

    LR2P = .5 * log(2.*M_PI);     /* Log Root 2 Pi */
    L10 = log(10.);             /* Log 10 */

    /* Get number of digits */
    if (argc>1) n = atol(argv[1]);
    if (n<1) n = N;

    kmax = invlfact(n) + 1;
    printf("Calculating e to %ld places, using %ld cells\n", n, kmax);

    /* Allocate table for factorial base digits */
    if (!(d = malloc((sizeof d)*kmax)))
    {
        printf("Insufficient memory: %ld bytes required\n", (sizeof d)*kmax);
        return 10;
    }

    /* Initialize with series for e-2 = 1/2! + 1/3! + ... */
    for (k=2; k<kmax; k++)
        d[k] = 1;

    printf("e ~= 2.\n");

    /* Get the next W digits by firstly multiplying d by A,
       propagating carries back down the array,
       then printing the integer part & removing it. */
    for (j=1; n>0; n-=W, j++)
    {
        char *ts;

        kmax = invlfact(n);
        for (c=0, k=kmax; k>1; k--)
        {
            d[k] = d[k] * A + c;
            c = d[k] / k;
            d[k] -=  c*k;
        }

        ts = j%2 ? "" :
             j%50 ? " " :
            j%200 ? "\n" : "\n\n";
        printf("%05d%s", c, ts);
    }
    printf("\n");

    free(d);

    return 0;
}

/* Inverse Stirling's approx for log n factorial */
long invlfact(long n)
{
    double x, y;
    int i;

    y = n * L10 - LR2P;
    x = y;
    for (i=0; i<3; i++)
        x = (y + x) / log(x);

    return (long)(x + .5);
}


phlip wrote:
PM 2Ring wrote:In an imperative language, I'd print each block of digits as I generate them, but I don't know how to do that sort of thing in Haskell, so I'm just collecting all the digits into a list & printing them out at the end.

Bear in mind that Haskell is lazy... so if your code is generating the digits (or blocks of digits) in order, and whatever you're passing them to on the IO side is looping over the list and printing them as they come (on both counts: probably) then laziness will do that for you.


Well, I'd like to generate the blocks of digits in an IO loop, but I'm not sure how to do that yet. I'm guessing that I need to use a monad (State ?) to hold the factorial-base list of tuples. Or is there some feature of the IO monad that I can exploit?

User avatar
Steax
SecondTalon's Goon Squad
Posts: 3038
Joined: Sat Jan 12, 2008 12:18 pm UTC

Re: Coding: Fleeting Thoughts

Postby Steax » Tue Jul 31, 2012 4:07 am UTC

God, PHP, why do you use foreach($list as $item)? Why can't you use the "in" keyword like every other good boy?
In Minecraft, I use the username Rirez.

User avatar
Xanthir
My HERO!!!
Posts: 5425
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Tue Jul 31, 2012 4:13 am UTC

JS is switching to "of" anyway, since they fucked up their "in" so badly.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Coding: Fleeting Thoughts

Postby PM 2Ring » Tue Jul 31, 2012 4:20 am UTC

tastelikecoke wrote:Today I tried to write a simple, in-place, quick sort in C. 24 hours later I realized that quick sort is an unstable sort, so I returned to a simple insertion sort.


Insertion sort is fine for small lists, but you really ought to use something better for big lists. How about merge sort?

tastelikecoke wrote:I should really code in C more often. Python's spoonfed me for a long time.


I can relate to that. It feels good to go back to C and get close to the metal again. Although for that real sense of ultimate CPU control, you can't beat assembler. :)

It can be an interesting exercise to implement qsort() etc in languages that don't permit recursive function calls - you basically have to manage your own call stack.


hotaru wrote:the standard doesn't say anything that would prevent qsort from using a stable sort, but
the GLIBC manual wrote:If you want the effect of a stable sort, you can get this result by writing the comparison function so that, lacking other reason distinguish between two elements, it compares them by their addresses. Note that doing this may make the sorting algorithm less efficient, so do it only if necessary.


I can't decide whether that technique's beautiful or ugly. :) And yeah, the C standard does not require qsort() to actually use the Quicksort algorithm. And even if it does, it most likely uses insertion sort (or perhaps selection sort) on small lists. In Ancient Times, I wrote a qsort() that used insertion sort on smallish lists and sorting networks on very small lists. Of course, it only recursed on the smaller partition and looped on the larger - the compiler I used didn't perform tail call optimisation.

User avatar
Steax
SecondTalon's Goon Squad
Posts: 3038
Joined: Sat Jan 12, 2008 12:18 pm UTC

Re: Coding: Fleeting Thoughts

Postby Steax » Tue Jul 31, 2012 4:24 am UTC

Xanthir wrote:JS is switching to "of" anyway, since they fucked up their "in" so badly.


Wait, JS did that? Why?
In Minecraft, I use the username Rirez.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6598
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Tue Jul 31, 2012 4:35 am UTC

Steax wrote:
Xanthir wrote:JS is switching to "of" anyway, since they fucked up their "in" so badly.


Wait, JS did that? Why?


See the first example for why:

https://developer.mozilla.org/en/JavaSc ... s/for...of
Summum ius, summa iniuria.

User avatar
Steax
SecondTalon's Goon Squad
Posts: 3038
Joined: Sat Jan 12, 2008 12:18 pm UTC

Re: Coding: Fleeting Thoughts

Postby Steax » Tue Jul 31, 2012 4:44 am UTC

Okay, looks like I didn't search hard enough. I... guess it makes sense. You confuse me so, javascript.
In Minecraft, I use the username Rirez.

User avatar
Xanthir
My HERO!!!
Posts: 5425
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Tue Jul 31, 2012 5:45 am UTC

The MDN article has details, but it's basically:

  • for-in goes over keys in everything, which is usually not what you want in arrays
  • for-in goes over all enumerable properties, including ones from your prototype, which is very rarely what you want (it's why adding things to Object.prototype or Array.prototype is so discouraged)
  • for-in reuses the same iteration variable in every iteration, so doing something simple like creating a closure in each loop that uses the iteration var is completely broken, as they'll all capture the same variable, set to the last value (for-of will use a fresh value if you use "let")
  • for-of will work nicely with generators and iterators
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
Steax
SecondTalon's Goon Squad
Posts: 3038
Joined: Sat Jan 12, 2008 12:18 pm UTC

Re: Coding: Fleeting Thoughts

Postby Steax » Tue Jul 31, 2012 6:17 am UTC

So basically for-of is just fixing what for-in should've done, as I see it. With backwards compatibility dressing.








I know I have a great job when all the languages/platforms I work with (HTML, CSS, JS, PHP, MySQL) are either a stupid puddle of mixed-up madness, or have horrifying inconsistencies between clients. Or both.
In Minecraft, I use the username Rirez.

User avatar
tastelikecoke
Posts: 1208
Joined: Mon Feb 01, 2010 7:58 am UTC
Location: Antipode of Brazil
Contact:

Re: Coding: Fleeting Thoughts

Postby tastelikecoke » Tue Jul 31, 2012 7:39 am UTC

PM 2Ring wrote:Insertion sort is fine for small lists, but you really ought to use something better for big lists. How about merge sort?

I have a maximum of 26 elements, so technically it shouldn't really matter. Implementing merge sort would probably end up in more debugging adventures.

Anyhow, If anyone's curious, our current curriculum uses Java and C. Which leads me a situation where I want to use OOP in C and pointers in Java. I wonder why didn't they just use C++ if they really like the industry standards.

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Tue Jul 31, 2012 8:26 am UTC

Code: Select all

Traceback (most recent call last):
  [snip]
ex = ProgrammingError('42000', '[42000] [Microsoft][SQL Server Native Client 10.0][SQL Server]The query processor ran out of stack space during query optimization. Please simplify the query. (8621) (SQLExecute)')
sql = 'DELETE FROM [table] WHERE [primarykey]=?'
How does this happen, mssql? How do you live with yourself? Or, more to the point, how am I supposed to live with you?

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jul 31, 2012 8:26 am UTC

tastelikecoke wrote:
PM 2Ring wrote:Insertion sort is fine for small lists, but you really ought to use something better for big lists. How about merge sort?

I have a maximum of 26 elements, so technically it shouldn't really matter. Implementing merge sort would probably end up in more debugging adventures.

Anyhow, If anyone's curious, our current curriculum uses Java and C. Which leads me a situation where I want to use OOP in C and pointers in Java. I wonder why didn't they just use C++ if they really like the industry standards.


Java is pass-by-reference. Everything but primitive types *is* a pointer of sorts. Primitive types you can stick in a 1 length array if you want pointer semantics.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
sourmìlk
If I can't complain, can I at least express my fear?
Posts: 6393
Joined: Mon Dec 22, 2008 10:53 pm UTC
Location: permanently in the wrong
Contact:

Re: Coding: Fleeting Thoughts

Postby sourmìlk » Tue Jul 31, 2012 9:38 am UTC

Well I assume there's semantic functionality or syntactic structure that he'd occasionally like to use from C that he can't in Java. Otherwise, yeah, he is using pointers in the sense that Java objects are pass-by-reference, and so he shouldn't have a problem.

Also I just learned about std::for_each after having been programming in C++ for a solid year or so (and longer intermittently). There's something seriously fucked up with how I learn a language. I learn the minimum I need to accomplish a task and then nothing else, which works great for C and absolutely nothing else with more than 4 features.
Terry Pratchett wrote:The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.

Ben-oni
Posts: 278
Joined: Mon Sep 26, 2011 4:56 am UTC

Re: Coding: Fleeting Thoughts

Postby Ben-oni » Tue Jul 31, 2012 10:08 am UTC

You, sir, name? wrote:Java is pass-by-reference.

This is unequivocally wrong. Java is strictly pass-by-value. Those values are always references, but that doesn't equate to pass-by-reference semantics.

Everything but primitive types *is* a pointer of sorts. Primitive types you can stick in a 1 length array if you want pointer semantics.

1-lenth arrays? Why, when just looking at a primitive funny causes it to run for a wrap?

User avatar
tastelikecoke
Posts: 1208
Joined: Mon Feb 01, 2010 7:58 am UTC
Location: Antipode of Brazil
Contact:

Re: Coding: Fleeting Thoughts

Postby tastelikecoke » Tue Jul 31, 2012 10:34 am UTC

Yeah, I mean Java doesn't allow the cool things dereferencing pointers allow. I'm pretty sure the "pointer semantics in primitives" is covered by Integer, Float, String, etc. classes. I've never seen 1-length arrays used in that way before.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jul 31, 2012 10:57 am UTC

tastelikecoke wrote:Yeah, I mean Java doesn't allow the cool things dereferencing pointers allow. I'm pretty sure the "pointer semantics in primitives" is covered by Integer, Float, String, etc. classes. I've never seen 1-length arrays used in that way before.


Integer, Float, etc. are immutable and, as such, quite worthless to pass around by reference. They might as well be primitives.

Ben-oni wrote:
Everything but primitive types *is* a pointer of sorts. Primitive types you can stick in a 1 length array if you want pointer semantics.

1-lenth arrays? Why, when just looking at a primitive funny causes it to run for a wrap?


1 length arrays are typically used for objects to work around the final constraint of anonymous inner class closures. In C terms, you're turning

Code: Select all

const foo* variable;
into

Code: Select all

foo* const variable;
by using an 1 length array.

Ben-oni wrote:
You, sir, name? wrote:Java is pass-by-reference.

This is unequivocally wrong. Java is strictly pass-by-value. Those values are always references, but that doesn't equate to pass-by-reference semantics.


If you pass a reference by value, you are passing by reference. As the value of the reference is a reference. Accepting your definition of pass-by-value would mean pass-by-reference is impossible, as all references are by necessity passed as values.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

ycc1988
Posts: 28
Joined: Fri Jun 22, 2012 5:13 am UTC

Re: Coding: Fleeting Thoughts

Postby ycc1988 » Tue Jul 31, 2012 11:10 am UTC

What is the difference between

Code: Select all

void foo(int x) {x = x+1;}

and

Code: Select all

void foo(Integer x) {x = x+Integer.valueOf(1);}

if any?

Ben-oni
Posts: 278
Joined: Mon Sep 26, 2011 4:56 am UTC

Re: Coding: Fleeting Thoughts

Postby Ben-oni » Tue Jul 31, 2012 11:13 am UTC

You, sir, name? wrote:
Ben-oni wrote:
You, sir, name? wrote:Java is pass-by-reference.

This is unequivocally wrong. Java is strictly pass-by-value. Those values are always references, but that doesn't equate to pass-by-reference semantics.


If you pass a reference by value, you are passing by reference. As the value of the reference is a reference. Accepting your definition of pass-by-value would mean pass-by-reference is impossible, as all references are by necessity passed as values.


No. I'm telling you three times, no.

Call-by-reference semantics requires an lvalue in the function call, and assigning to the parameter changes the variable passed in. Call-by-value does not. The difference between passing references by value and call-by-reference may be semantics, but that's why it's referred to as language semantics.

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Tue Jul 31, 2012 11:18 am UTC

ycc1988 wrote:What is the difference between [...]
Nothing. The latter one nominally has to do more work (you're explicitly wrapping 1 in an object, and then implicitly immediately unwrapping that 1 and also x to do the addition, and then re-wrapping everything in an object again) but in all likelihood that's being optimised away by the JIT anyway. At least I presume so, I don't know too many specifics about the JIT's optimiser. In neither case is there any effect in the caller, and the whole function is a no-op.

The point of Integer et al is that an "int" variable and an "Integer" variable are very similar when it comes to copy semantics and the like (because of the immutability), so you can use the former when you need to be able to perform arithmetic without the OO layer getting in the way of performance, and you can use the latter when you need something that descends from Object.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Tue Jul 31, 2012 2:12 pm UTC

tastelikecoke wrote:Yeah, I mean Java doesn't allow the cool things dereferencing pointers allow. I'm pretty sure the "pointer semantics in primitives" is covered by Integer, Float, String, etc. classes. I've never seen 1-length arrays used in that way before.
For a single value I can't really see a reason to do so, as that's usually what the return value on a function would do.

It becomes more useful if you want to return multiple values from a function, because as far as I'm aware there isn't a simple way to do so in Java, so you end up having to juggle an array (or create a custom Tuple object). But even then you could just return a single array with multiple elements.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jul 31, 2012 2:34 pm UTC

Somewhat contrived example time:

Code: Select all

int division(int x, int y, int* remainder) {
   if(remainder) *remainder = x % y;
   return x / y;
}

You can write an equivalent function in Java with

Code: Select all

int division(int x, int y, int[] remainder) {
   if(remainder != null && remainder.length > 0) remainder[0] = x % y;
   return x / y;
}


This isn't widely used because there's rarely ever a reason to use it, but you can do it. The typical reason you'd see this type of code in C is when you want to indicate the success of the function as well as optionally return some other value. In Java, you use exceptions to accomplish this.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Tue Jul 31, 2012 3:08 pm UTC

You, sir, name? wrote:The typical reason you'd see this type of code in C is when you want to indicate the success of the function as well as optionally return some other value. In Java, you use exceptions to accomplish this.
Yea, personally I just think using an array like that is hideous. :wink:

*Goes back to C# and hugs the out/ref keywords*

Ben-oni
Posts: 278
Joined: Mon Sep 26, 2011 4:56 am UTC

Re: Coding: Fleeting Thoughts

Postby Ben-oni » Tue Jul 31, 2012 7:24 pm UTC

Thought of the Day: Race conditions are hard when they happen in the Real World(tm). Lesson Learned: Doing concurrency right is especially important when it happens beyond program control.

User avatar
Steax
SecondTalon's Goon Squad
Posts: 3038
Joined: Sat Jan 12, 2008 12:18 pm UTC

Re: Coding: Fleeting Thoughts

Postby Steax » Tue Jul 31, 2012 7:29 pm UTC

The thing I hate about race conditions is that they're awfully hard to detect. Things just went wrong and without some sort of extremely low-level log, it just looks like the code magically managed to mangle some data. They have to be consciously preempted, which is kinda hard in larger teams.
In Minecraft, I use the username Rirez.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11129
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Tue Jul 31, 2012 8:22 pm UTC

It is one of the reasons why people really, really like solid abstractions for concurrency related tasks.

Much like a crypto module, if you are writing it, you are doing something wrong.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jul 31, 2012 8:27 pm UTC

Can't help but feel a lot the ways multi-threaded computing is handled in languages is immature. Locks and mutexes are the assembly of parallel computing. It should be abstracted away in higher level languages into something that is at least a bit less of a mine field to work with.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Tue Jul 31, 2012 8:49 pm UTC

You, sir, name? wrote:Can't help but feel a lot the ways multi-threaded computing is handled in languages is immature. Locks and mutexes are the assembly of parallel computing. It should be abstracted away in higher level languages into something that is at least a bit less of a mine field to work with.

Much of it is a lack of understanding.

Locks and mutexes have wonky syntax in many languages, or a complete lack of it. I've run into a few cases where the abstraction I wanted did not exist, so I wrote it myself on top of mutexes.
Programmers tend to not understand what they are doing as a result. They get lost in the details of "what the hell does volatile mean" and don't see the high-level structure of a mutex as a thing that's either empty or full.

Haskell solves the problem by having a complete lack of syntax for just about anything real-world, which lets the programmer use the same absense-of-syntax for references, arrays, mutexes, transactions, and more. There's almost certainly a better way than this...
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Tue Jul 31, 2012 9:19 pm UTC

headprogrammingczar wrote:
You, sir, name? wrote:Can't help but feel a lot the ways multi-threaded computing is handled in languages is immature. Locks and mutexes are the assembly of parallel computing. It should be abstracted away in higher level languages into something that is at least a bit less of a mine field to work with.

Much of it is a lack of understanding.

Locks and mutexes have wonky syntax in many languages, or a complete lack of it. I've run into a few cases where the abstraction I wanted did not exist, so I wrote it myself on top of mutexes.
Programmers tend to not understand what they are doing as a result. They get lost in the details of "what the hell does volatile mean" and don't see the high-level structure of a mutex as a thing that's either empty or full.


It's uncivilized to require that sort of awareness of underlying voodoo to do everyday programming. The mutexes and barrier instructions feels like using assembly-style jump instructions to structure your code, and similar to that, designing and maintaining the code turns into cat-herding in all but the most trivial cases.

I think, by adding more explicit guarantees against side effects, you could reap the benefits of implicit parallelism.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Tue Jul 31, 2012 9:44 pm UTC

You, sir, name? wrote:I think, by adding more explicit guarantees against side effects, you could reap the benefits of implicit parallelism.
Yea, but short of a functional language where side effects can't happen (monads? bleh), how do do that? Or is the answer to just make all objects immutable that don't exist exclusively inside the current scope (assuming you can guarantee that somehow)?

User avatar
sourmìlk
If I can't complain, can I at least express my fear?
Posts: 6393
Joined: Mon Dec 22, 2008 10:53 pm UTC
Location: permanently in the wrong
Contact:

Re: Coding: Fleeting Thoughts

Postby sourmìlk » Thu Aug 02, 2012 1:23 am UTC

How do I know if I'm writing decent code? I think I am, because I understand it and can reuse it easily to do what I want, but that's remarkably subjective. Is there really a way to tell if you don't work in a team?
Terry Pratchett wrote:The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.

Ben-oni
Posts: 278
Joined: Mon Sep 26, 2011 4:56 am UTC

Re: Coding: Fleeting Thoughts

Postby Ben-oni » Thu Aug 02, 2012 5:04 am UTC

sourmìlk wrote:How do I know if I'm writing decent code? I think I am, because I understand it and can reuse it easily to do what I want, but that's remarkably subjective. Is there really a way to tell if you don't work in a team?

One simple test is to ask how hard it is to change the code. If the code needs to be altered to do something fairly close to what it currently does, well-structured code need only be altered in a few locations. The more invasive the changes need to be, the worse the code.

User avatar
sourmìlk
If I can't complain, can I at least express my fear?
Posts: 6393
Joined: Mon Dec 22, 2008 10:53 pm UTC
Location: permanently in the wrong
Contact:

Re: Coding: Fleeting Thoughts

Postby sourmìlk » Thu Aug 02, 2012 5:23 am UTC

Ben-oni wrote:
sourmìlk wrote:How do I know if I'm writing decent code? I think I am, because I understand it and can reuse it easily to do what I want, but that's remarkably subjective. Is there really a way to tell if you don't work in a team?

One simple test is to ask how hard it is to change the code. If the code needs to be altered to do something fairly close to what it currently does, well-structured code need only be altered in a few locations. The more invasive the changes need to be, the worse the code.


I like this test because it gets to the point. The primary reason code needs to be well-written is so it can be revisited and altered. Thus the most direct test is to alter / revisit it. So far, the only changes I've made have been giant ones (because the code wasn't great), but if I have to make a smaller one from now on I'll keep this in mind.
Terry Pratchett wrote:The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.


Return to “Coding”

Who is online

Users browsing this forum: Dason and 9 guests