Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-8081-

Teach me to remove bloat!

Name: Anonymous 2010-02-24 0:34

Hey guys, I would like some pointer (no, not that kind) on removing bloat in code. Here is a fully functional piece of code that I wrote which I'm worried about bloat in. How do I shorten this?

int get_input()
{
    int count, paren_count, total_count, c;
    char *input, *temp;

    input = (char *) malloc (500 * sizeof (char));

    if (input == NULL) return 0;
    printf("%% ");
    for (count = paren_count = total_count = 0; (c = getchar()) != EOF; count++, input++, total_count++)
    {
        if (count == 499)
        {
            input -= total_count;
            temp = (char *) realloc (input, (500 + total_count) * sizeof (char));
            if (temp == NULL)
                return 0;
            input = temp;
            input += total_count;
        }
        if (c == '\n')
        {
            *input = '\0';
            temp = input;
            temp -= (count);
            count = 0;
            for (; *temp != '\0'; temp++)
            {
                if (*temp == '(')
                    paren_count++;
                else if (*temp == ')')
                    paren_count--;
            }
            if (paren_count == 0)
                break;
            printf("  ");
        }
        *input = c;
    }
    *temp = '\0';
    input -= total_count;
    printf("%s\n", input);
    free(input);
    return 0;
}

Name: Anonymous 2010-02-24 0:42

here, OP, let me help you with the first step:


int get_input()
{
    int count, paren_count, total_count, c;
    char *input, *temp;

    input = (char *) malloc (500 * sizeof (char));

    if (input == NULL) return 0;
    printf("%% ");
    for (count = paren_count = total_count = 0; (c = getchar()) != EOF; count++, input++, total_count++)
    {
        if (count == 499)
        {
            input -= total_count;
            temp = (char *) realloc (input, (500 + total_count) * sizeof (char));
            if (temp == NULL)
                return 0;
            input = temp;
            input += total_count;
        }
        if (c == '\n')
        {
            *input = '\0';
            temp = input;
            temp -= (count);
            count = 0;
            for (; *temp != '\0'; temp++)
            {
                if (*temp == '(')
                    paren_count++;
                else if (*temp == ')')
                    paren_count--;
            }
            if (paren_count == 0)
                break;
            printf("  ");
        }
        *input = c;
    }
    *temp = '\0';
    input -= total_count;
    printf("%s\n", input);
    free(input);
    return 0;
}

Name: Anonymous 2010-02-24 1:30

Use a better language, I guess.

(defun get-input (&optional (stream *terminal-io*))
  (with-output-to-string (input)
    (prog (i (p 0))
     loop
     (setf i (read-line stream nil nil)
           p (+ p (count-parens i)))
     (write-string i input)
     (if (or (null i)
             (zerop p))
         (return)
         (go loop)))))

(defun count-parens (string)
  (loop for x across string
     summing (case x
               (#\( 1)
               (#\) -1)
               (t 0))))

Name: Anonymous 2010-02-24 1:37

>>3
I'm trying to write the shell for an interpreted language, it wouldn't make much sense to write it in another interpreted language.

Name: Anonymous 2010-02-24 2:16

int getInput() {
    int size = 500, count = 0;
    char* input = malloc(size * sizeof(char)), c;
    printf("%% ");
    for(;(c=getchar())!=EOF; ++count) {
        if(count>=size-1) {
            size *= 2;
            input = realloc(input, size * sizeof(char));
        }
        input[count] = c;
        if(c=='\n') {
            input[count+1]='\0';
            if(!countParens(input)) break;
            printf("  ");
        }
    }
    input[count] = '\0';
    printf("%s\n", input);
    free(input);
    return 0;
}
int countParens(const char* s) {
    int n = 0;
    for(;*s;s++) n += *s=='('?1:*s==')':-1:0;
    return n;
}

Name: Anonymous 2010-02-24 2:23

>>4
Then you need more FIOC.

Name: Anonymous 2010-02-24 3:23

>>4
Lisp ... interpreted
Wut.

Name: Anonymous 2010-02-24 3:50

This must be a troll. Your program is a borderline IOCCC case. Read K&R.

Name: Anonymous 2010-02-24 3:53

>>5
Your unidiomatic use of for loops makes me sick.

Name: Anonymous 2010-02-24 6:01

UNTeSTED


int get_input() {
    int n,p,t,c;
    char *inp,*tmp;

    if(!(inp=malloc(500))
      return 0;

    printf("%% ");
    for(n=p=t=0;(c=getchar())!=EOF;n++,inp++,t++) {
        if(count==499) {
            inp -= t;
            if(!(tmp=realloc(inp,500+t))
              return 0;
            inp = tmp + t;
        }
        if(c=='\n') {
            *input = 0;
            tmp = inp;
            tmp -= n;
            n = 0;
            for(;*tmp!='\0';tmp++)
                p+=(*tmp=='(')?1:((*tmp==')')?-1:0);
            if(!p)
                break;
            printf("  ");
        }
        *inp = c;
    }
    *tmp = 0;
    inp -= t;
    printf("%s\n",inp);
    free(inp);
    return 0;
}

Name: Anonymous 2010-02-24 6:40

First of all, remove all the useless white spaces. Also change all of your variable names to shorter ones.

int get_input(){int u,p,t,c;char *i,*m;i=(char*)malloc(500*sizeof(char));if(i==NULL)return 0;printf("%% ");for(u=p=t=0;(c=getchar())!=EOF;u++,i++,t++){if(u==499){i-=t;m=(char*)realloc(i,(500+t)*sizeof(char));if(m==NULL)return 0;i=m;i+=t;}if(c=='\n'){*i='\0';m=i;m-=(u);u=0;for(;*m!='\0';m++){if(*m=='(')p++;else if(*m==')')p--;}if(p==0)break;printf("  ");}*i=c;}*m='\0';i-=t;printf("%s\n",i);free(i);return 0;}

ENTERPRISE QUALITY OMPIMIZATION

Name: Anonymous 2010-02-24 7:05

>>11
FrozenVoid Quality.

Name: Anonymous 2010-02-24 7:05

>>11
ZOMG OPTIMISED
#define return R
#define printf P
int g(){int u,p,t,c;char *i,*m;i=(char*)malloc(500*sizeof(char));if(i==0)R 0;P("%% ");for(u=p=t=0;(c=getchar())!=-1;u++,i++,t++){if(u==499){i-=t;m=(char*)realloc(i,(500+t)*sizeof(char));if(m==0)R 0;i=m;i+=t;}if(c=='\n'){*i='\0';m=i;m-=(u);u=0;for(;*m!='\0';m++){if(*m=='(')p++;else if(*m==')')p--;}if(p==0)break;P("  ");}*i=c;}*m='\0';i-=t;P("%s\n",i);free(i);R 0;}

Name: Anonymous 2010-02-24 7:16

>>13
You should move the lines
#define return R
#define printf P


to your void.h file.

Name: Anonymous 2010-02-24 7:26

>>14
I nearly spit my juice[1] on the keyboard.

--------------------------------
1- On the left in this image: http://www.kagome.co.jp/news/2008/images/090108001.jpg - pretty tasty

Name: Anonymous 2010-02-24 7:29

>>14
If we are going to allow modifications we could add a lot more to it
#define GC getchar
#define C  char
#define M  malloc
#define SO sizeof
#define RA realloc
#define I  int
#define B  break
#define F  free
#define P  printf
#define R  return
#define Q  if
#define EF else if
#define FR for

and then have
I g(){I u,p,t,c;C *i,*m;i=(C*)M(500*SO(C));Q(i==0)R 0;P("%% ");FR(u=p=t=0;(c=GC())!=-1;u++,i++,t++){Q(u==499){i-=t;m=(C*)RA(i,(500+t)*SO(C));Q(m==0)R 0;i=m;i+=t;}Q(c=='\n'){*i='\0';m=i;m-=(u);u=0;FR(;*m!='\0';m++){Q(*m=='(')p++;EF(*m==')')p--;}Q(p==0)B;P("  ");}*i=c;}*m='\0';i-=t;P("%s\n",i);F(i);R 0;}

Thne we should replace everything that is >1 letter long with a single character.

Name: Anonymous 2010-02-24 7:30

>>16
s/modifications/modifications to void.h/

Name: Anonymous 2010-02-24 7:33

>>16
it's almost as unreadable as perl

Name: Anonymous 2010-02-24 7:36

>>16
;_; even FV didn't use one char identifiers. This hurts my eyes.

Name: Anonymous 2010-02-24 10:13

>>16
If we allow a header file we could even OMPTIMIZE even further:

h.h
#define GC getchar
#define C  char
#define M  malloc
#define SO sizeof
#define RA realloc
#define I  int
#define B  break
#define F  free
#define P  printf
#define R  return
#define Q  if
#define EF else if
#define FR for
#define G  I g(){I u,p,t,c;C *i,*m;i=(C*)M(500*SO(C));Q(i==0)R 0;P("%% ");FR(u=p=t=0;(c=GC())!=-1;u++,i++,t++){Q(u==499){i-=t;m=(C*)RA(i,(500+t)*SO(C));Q(m==0)R 0;i=m;i+=t;}Q(c=='\n'){*i='\0';m=i;m-=(u);u=0;FR(;*m!='\0';m++){Q(*m=='(')p++;EF(*m==')')p--;}Q(p==0)B;P("  ");}*i=c;}*m='\0';i-=t;P("%s\n",i);F(i);R 0;}


whatever.c
#include "h.h"

G

Name: Anonymous 2010-02-24 10:39

>>20
 ______
[ul](-_ -  )[/ul]

Name: Anonymous 2010-02-24 10:45

>>8
I'm not, and I already have. The plan was to get this to work first and then clean it up.
>>5
Input = realloc (input,...)
Realloc isn't gauranteed to work fool.

Name: Anonymous 2010-02-24 10:49

>>22
GUARANTEE MY ANUS

Name: Senior Anonix Developer 2010-02-24 11:14

>>5 uses exponential instead of linear allocation
>>10 didn't change much
>>11,13,16,20 IOCCC'd versions of OP

int get_input() {
 int len = 0, ulen = 0, pc = 0;
 char *input = 0, c;
 printf("%% ");
 while((c=getchar())!=EOF) {
  if(ulen>=len) {
   input = realloc(input,len+=500);
   if(!input)
    return 0;
  }
  if(c=='\n')
   if(pc)
    putchar(' ');
   else {
    input[ulen++] = 0;
    break;
   }
  else
   pc += (c=='(')?1:(c==')')?-1:0;
  input[ulen++] = c;
 }
 puts(input?input:"");
 free(input);
 return 0;
}


If you replace the putchar(' ') with printf("%*c",pc,' '), you get auto-indentation too.

Name: Anonymous 2010-02-24 11:37

You could start by using comments...

Name: Anonymous 2010-02-24 12:19

Congratulations.  We've taken a very modest function and rendered it illegible.

Name: Anonymous 2010-02-24 12:41

int get_input(void) {
  char* input;      
  int c, n, parens; 
  int incr = 500;   

  // get a buffer for storage
  if (!(input = (char*) malloc(incr)))
    return -1;                       
  n = parens = 0;                    

  // read until EOF or newline with balanced parens
  printf("%% ");                                  
  while ((c = getchar()) != EOF) {                
    if (c == '\n' && parens <= 0)                 
      break;                                      
    input[n++] = c;                               

    // handle parens
    if (c == '(')  
      ++parens;    
    else if (c == ')')
      --parens;      

    // grow buffer
    if (n % incr == 0)
      if (!(input = (char*) realloc(input, n + incr)))
        return -1;                                   
  }                                                  

  // done
  input[n] = 0;
  if (c == EOF) printf("\n");
  printf("%s\n", input);    
  free(input);              
  return c == EOF ? -1 : 0; 
}


- pulls out increment as a constant
- returns -1 on failure (you were returning 0 everywhere for some reason)
- checks for end of file (ctrl+d or closed pipe)
- checks for too many closing parens
- adds CODE COMMENTS, so you can actually see what's going on

Name: Anonymous 2010-02-24 12:44

>>27
- also, doesn't fuck around with your input pointer, so you can use it with garbage collectors and other analysis tools. It's a little scary that OP doesn't keep a fixed pointer to the start of the buffer.

Name: Anonymous 2010-02-24 13:24

>>28
fag

Name: Anonymous 2010-02-24 14:04

is this a side effect generator?

Name: Anonymous 2010-02-24 14:14

>>26

illegible
Isn't it the real point of /prog/?

Name: GRUNNUR 2010-02-24 14:16

GRUNNUR

Name: Anonymous 2010-02-24 17:24

>>25
You seriously need comments to understand this?

Name: Anonymous 2010-02-24 17:25

This does a lot more than you want it to do, but it's more generic:
(read)

Name: Anonymous 2010-02-24 17:56

>>22
You think I give a shit if realloc works or not? You think his program is going to be able to gracefully degrade if it runs out of memory? Get the fuck out with your useless pedantry.

Name: Anonymous 2010-02-24 18:24

>>35
My program? Frankly, I like protection.
Anyway today I fixed the bloat issue. I'll post it later for show.

Name: Anonymous 2010-02-24 18:42

>>36
Those who give up efficiency for security deserve neither.

Name: Anonymous 2010-02-24 19:04

>>37
Okay here's the thing: I am writing an interpreted programming language, this function is part of the shell.
God damn, I need to free all of the memory in the linked list before it exits, or else bad things will happen, and you know it.

Name: Anonymous 2010-02-24 19:14

>>38
Why don't you just write it in a higher level language? Until you have it working, worrying about efficiency is a waste.

Name: Anonymous 2010-02-24 19:50

>>39
I hate higher level languages in general (save for languages like scheme and perl), plus the linked lists are so much easier in C. And you're right, worrying about efficiency in the beginning is stupid, I was just saying how safety is necessary for what I'm doing.

Any way, here's my fixed version. Sorry if I don't get the bbcode right

int get_input()
{
    int count, post_count;
    char *input = NULL, *temp, c;

    printf("%% ");
    for (count = 0; (c = getchar()) != EOF; count++)
    {
        if (count % 500 == 0)
        {
            if ((temp = (char *) realloc (input, (500 + count) * sizeof (char))) == NULL)
            {
                free (input);
                return 2;
            }
            input = temp;
        }
        input[count] = c;
        if (c == '\n')
        {
            input[count + 1] = '\0';
            temp = input;
            post_count = 0;
            while (*temp != '\0')
            {
                if (*temp == '(')
                    post_count++;
                else if (*temp == ')')
                    post_count--;
                temp++;
            }
            if (post_count > 0)
                printf("  ");
            else
                break;
        }

    }
    printf("%s\n", input);
    free(input);
    return 0;
}

Name: Anonymous 2010-02-24 20:21

It's funny how people want efficiency, so they use C, sometimes they want to embed a language, but then they realize making a full compiler would be too much work for them, so they end up making an interpreter, which would mean overall slower code execution (the only time when interpreters beat compilers is when the expressions are short and easy to interpret, as well as situations when your interpreted code calls EVAL internally for everything it does - which is not a good programming practice (lol FEXPRS)). Instead they could choose something more high-level, but on average slightly slower than C (unless more work is done to optimize things), which allows code transformation, and gives you direct runtime access to a compiler. Such a language could be Common Lisp, but it's not the only one(however it's one of the few languages which support real macros).

Name: >>41 2010-02-24 20:23

Which would in the end give you faster execution than what interpreted code could give you, and if you really wanted fast EVAL for some reason? Just switch to a CL implementation with a fast compiler or interpreter - little to no code modification required.

Name: Anonymous 2010-02-24 20:28

>>41
I never wanted to make a compiler, actually.

Name: Anonymous 2010-02-24 20:33

>>40
Comment your code, jesus fucking christ.

>>33
You don't need comments to understand it; you need comments to understand it quickly.

Also, I really don't see how anything in this thread is related to 'bloat'.

Name: Anonymous 2010-02-24 20:35

>>43
Why not? Making compilers isn't THAT hard, but if you could reuse a good compiler backend, that saves you a lot of time, especially if you can switch backends at any time (such as with CL).

Name: Anonymous 2010-02-24 20:39

>>41
but then they realize making a full compiler would be too much work for them, so they end up making an interpreter,
It's not (just) that making a compiler is a lot of work, it's that traditional ways of making a compiler mean a lot of upfront work before you get any results. Abdulaziz Ghuluom has a paper on incremental compiler construction which is interesting and should give the same instant gratification you get from writing interpreters.
the only time when interpreters beat compilers is when the expressions are short and easy to interpret, as well as situations when your interpreted code calls EVAL internally for everything it does
That depends on whether or not we count JITs as interpreters. Most people wouldn't, I guess, but I see no reason to assume that we can't make fast interpreters. As an aside, if you are going to be calling eval on every expression, why don't you just implement your language as a series of reader macros (assuming that this was Lisp)?

Name: Anonymous 2010-02-24 20:40

>>44
Also, I really don't see how anything in this thread is related to 'bloat'.
When do we ever stay on topic

Name: Anonymous 2010-02-24 21:11

>>46
If you're making a completly new language, there's no real reason to bother with reader macros(unless you want to add support for the language in the standard reader). Just make a new reader which lexes and parses the language, and gives you an AST(in form of S-EXPRs, or something else), and then you transform that AST into lisp code using some macro system of your own making (or just plain simple macros - this doesn't matter much, as reimplementing the macro system can be done with very little effort(it's just simple code transforms registered in a global environment)), after the code transforms have been performed, you just end up with a set of special forms which can be compiled, or you could transform the code to plain old lisp forms, which can then be passed to COMPILE. Basically, you're making a front-end for a compiler which converts your language to lisp, which can then be compiled directly at runtime.

Name: Anonymous 2010-02-24 21:25

>>45
Because I want to make it cross platform, for one thing. I'm considering putting a compiler in there for people who want to make a standalone, so it's not entirely ruled out as a possibility.

Name: Anonymous 2010-02-24 22:06

>>49
There's CL compilers which compile to C and some interpreters written in C, those should not be limited to CPU arch (that said, how many platforms do you intend to support? Most major ones have CL compilers working on them, but I guess not all of them. Maybe Scheme would be a simpler choice for this, however ECL should fit the bill too.)

Name: Anonymous 2010-02-24 22:09

>>50
Thanks, I'll check them out.

Name: Anonymous 2010-02-24 22:27

>>49
Then compile it to portable assembler.

Name: Anonymous 2010-02-24 23:17

>>49
Compile to Java Byte Code, dumbass!

Name: Anonymous 2010-02-24 23:20

>>53
I.
Hate.
Java.
So.
Much.

Name: Anonymous 2010-02-24 23:23

>>54
I also hate the Java language, and most of the libraries. But does that really devalue the benefits of the JVM?

Name: Anonymous 2010-02-24 23:24

>>55
Yes.

Name: Anonymous 2010-02-24 23:27

>>55
>implying one of the reasons I don't hate Java is because of its speed.

Name: Anonymous 2010-02-24 23:41

>>55
No, but the JVM is shit to begin with, due to shortsighted issues like the lack of tail recursion and the atrocious startup time. A more professional way to do it is with a runtime that allows you to deploy compiled binaries, such as SBCL's.

Name: Anonymous 2010-02-25 0:23

WHO BROKE PRAGUE ;_;

Name: Anonymous 2010-02-25 0:32

>>57
>implying
Please don't do that. Also, learn to quote.

Name: Anonymous 2010-02-25 4:54

>>4
Write it in ECL

Name: Anonymous 2010-02-25 7:22

*sizeof(char)
Stopped reading there.

Name: Anonymous 2010-02-25 8:13

>>62
char is not fixed by the c standard. Lrn2 CHAR_BIT

Name: !/c/0NTHWZ6 2010-02-25 8:24

.

Name: Anonymous 2010-02-25 9:53

>>62,63
C99 6.5.3.4 p.3
"When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1."

Name: Anonymous 2010-02-25 11:43

>>63
CHAR_BIT gives the number of bits in a byte on the current platform. char is always exactly one byte (even in C89), however many bits that may be.

Name: Anonymous 2010-02-25 13:24

>>65
>>66
YOU HAVE BEEN C TROLLED

Name: Anonymous 2010-02-26 13:57

Common Lisp is a really bad choice if you're looking for ways to reduce bloat. It will eat up 30-60MB RAM depending on the implementation. And that's just the Lisp environment itself without any of your own code.
Unless you're using something like CLISP (~8MB), but it's slow.

Name: Anonymous 2010-02-26 14:10

>>68
oh noes 30MB of RAM

Name: Anonymous 2010-02-26 14:22

>>68
Is that true? That's too horrible to be true.

Name: Anonymous 2010-02-26 14:57

>>70
you better believe it

Name: Anonymous 2010-02-26 15:01

>>70
It's your whole environment, the compiler and what not.

Name: Anonymous 2010-02-26 15:08

>>71,72
But we didn't have 30 (or even 8) megabytes handy back in the... sixties. I refuse to believe that bloat predates capacity. That would be a world too cruel for life.

Name: Anonymous 2010-02-26 15:26

>>73
CALM THE FUCK DOWN HOLY SUSSMAN

Name: Anonymous 2010-02-26 16:22

>>70
>>73
That's the price you pay when you're trying to emulate an incompatible LISP computer instead of acting like a proper program on the actual operating system. No sharing any memory either if you fire up multiple programs. It's sad.

Name: Anonymous 2010-02-26 16:49

>>74
I am calm. And I don't believe in SUSSMAN.

>>75
So what you're trying to say is faggotLISP is dead! Long live Lisp!faggot -- ?

Name: Anonymous 2010-02-26 16:57

>>76
Don't believe in The Sussman, believe in The Sussman who believes in you.

Name: Anonymous 2010-02-26 17:00

>>76
I'm just trying to say that current Common Lisp implementations are doing it wrong. Lisp machines are dead. They should stop trying to act like one.

Name: Anonymous 2010-02-26 18:39

>>68,78
If you want small memory footprint and memory sharing (copy-on-write), just use ECL. The runtime is in a shared library, and actual applications are tiny.

I actually like those "huge" image-based lisps as they're 100% dynamic in what you can change at runtime (want to recompile a piece of SBCL's kernel, sure, it's just one hotkey away! Hotpatching as never been easier), and the memory footprint being some 30mb doesn't bother me since I don't use a computer from 20 years ago.

Name: Anonymous 2010-02-26 21:31

>79
Even with ECL the runtime overhead is around 26MB.
Per program, I just checked. Unless, of course, you run it as a "Lisp server" with each program running in a different thread. At least that's how it's supposed to be done from what I've read.

How do you do it?

Name: Anonymous 2010-02-26 21:36

>>80
Either way works just fine really, but beware that if a thread patches some system routines or global values, this could interfere with the other threads and mess things up. I guess those are the dangers of shared program memory. It's not nearly as bad as with the old DOS/Win3.11 shared-memory aproaches since Lisp is much more high-level, but it's still possible for an application to easily crash the whole world if it wants to.

Name: Anonymous 2010-02-26 21:52

>>78
So, it's more of a [i]fag[...] Sussman is dead. - LISPgot[i] type situation then. (Try not to mind my active ``faggot-quotes'' research.)

>>79
I can appreciate the utility of a 30MB overhead, but I like to write for small devices. I know almost everything has at least 128MB these days, but my preferred target platform only has 4.

It's okay though. There are lispy enough things that aren't so um bad.

Name: Anonymous 2010-02-26 21:59

>>82
Well, CL was never intended to be that tiny, maybe some 8MB for a full CL, but I have my doubts. R5RS' could be smaller I guess, or maybe some Lisp500 variant.

Name: Anonymous 2010-02-26 22:36

Name: Anonymous 2010-02-26 23:08

>>82

U mena faghaskalgot

Name: Anonymous 2010-02-26 23:13

Those who thinkk 30MB is nothing should consider that the entire UNIX V7 operating system was less than 10MB.

Name: Anonymous 2010-02-27 0:37

>>85
Yeha thaanks. The BBCode is not with me tonight.

>>86
Most /prog/lodytes probably don't even consider that to be an interesting fact.

Name: Anonymous 2010-02-27 1:41

>>87
Most /prog/lodytes
*gasp* all three of them?

Name: Anonymous 2010-02-27 3:56

>>86
Tinycore linux is 10mb.

Name: Anonymous 2010-02-27 5:16

>>88
Well no, only two of them.

The other one is probably the guy too obsessed with [biou]my hanux[/biou] to register a thought one way or the other.

Name: Anonymous 2010-02-27 9:00

>>90
Who wouldn't be, it's a very nice anus, Mr. The Sussman

Name: ​​​​​​​​​​ 2010-09-07 23:02

Name: Anonymous 2010-12-24 17:17

Name: Anonymous 2011-02-03 1:11


Don't change these.
Name: Email:
Entire Thread Thread List