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

Pages: 1-

Using Global Variables

Name: Anonymous 2010-12-26 13:42

... in a Library is worse than murder.

Satan himself will arise from the depths of Oblivion to tear apart your soul for that.

Name: Anonymous 2010-12-26 13:48

What about Sinatra?

get '/' do
  puts 'hehehe'
end


It makes for nice syntax

Name: Anonymous 2010-12-26 13:58

I can think of plenty of legitimate cases where one would use globals in a dynamically linked library. Most stdlib(libc) implementations have plenty of globals in them (think for a bit, you'll find enough of them being documented, like stdin/stdout/stderr). The most common case is where the library initializes a shared resource or object of some kind (of which you only need one instance that can be used by everything else). It's especially important if it's a resource which takes a while to initialize and doing so would cost plenty of resources. Or it could be a global cache of sorts which is again costly to recreate it time and thus it would defeat the whole purpose of the cache. On the other hand, in most OSes, you can load the same library multiple times if you really want to avoid such unique globals.

I can't think of a single implementation of any language which doesn't use globals in some way, no matter how hard they may try to not use them. Shared resources are everywhere (your CPU, RAM, GPU, NIC are such resources...), get used to it!

Name: Anonymous 2010-12-26 14:04

>>1
What about using a language with a decent module system?
#lang racket/load
(module a racket
   (provide set!-d get-d)
   (define d 2)
   (define (set!-d x) (set! d 2))
   (define (get-d) d))
(require 'a)
(get-d) ; => 2
(set!-d 3) ; d = 3
(get-d) ; => 3
d ; Unbound variable


(in before "eww parens" and "lol toy language", Racket's not the only language with non-crappy modules (Python's is pure _shit))

Name: Anonymous 2010-12-26 14:07

>>3
Most stdlib(libc) implementations have plenty of globals in them
Everyone cries about strtok using a global variable to store the string.
Using globals without mutexes considered harmful.

Name: >>3 2010-12-26 14:12

>>5
It depends on what kind of global and how it's handled (to assure thread-safety). strtok is so terrible that I've written my own implementation which is thread-safe. However, certain kinds of globals such as those which either contain read-only data, or data which is modified in an atomic and thread-safe fashion are usually fine. Also, dynamicly scoped "globals" as Common Lisp has are pretty safe too. Global resources which are managed through a thread-safe API are also fine (even if there's only one resource in the underlying code).

Name: Anonymous 2010-12-26 14:14

>>4
eww parens

Name: Anonymous 2010-12-26 14:14

>>4
lol toy language

Name: Anonymous 2010-12-26 14:20

>>1
It's easy to use globals even in C libraries without problems. Present a problematic scenario and I'll give you a solution.

>>3
Global variables are different from (shared) system resources. More importantly, system resources are managed differently by the language and its standard library than the global scope is in virtually every language. Even when the global scope contains system resource facilities it's almost always an interface to manage the resource rather than the resource itself (common exceptions are per-process allocated resources, such as stdin/stdout) and it's a standard part of the language/target platform; never a gotcha that some library developer springs on you.

Name: Anonymous 2010-12-26 14:24

>>3
Sorry for my lack of details in >>1; I was referering to libraries who this kind of thing (I won't name it... *cough*OMG GLORIOUS OpenGL*cough):


     int main()
     {
         int c;
         object_initiate("poop/somefile.txt");
         while((c = object_get()) != -1)
         {
             ...
         }
         object_destroy();
}


.. It makes me want to punch someone.

Name: Anonymous 2010-12-26 14:32

>>10
That's troublesome since if your goal is to go through all the "objects", object_get might be called from another thread, or maybe even within that loop somewhere, which might lead to some objects being skipped in that loop. It's essentially a case of using globals for short-lived data, for which local variables should be used instead. Globals should be used for data which lives mostly as much as the entire code does (in memory).

Name: Anonymous 2010-12-26 16:52

All counters should be global variables

Name: Anonymous 2010-12-26 19:48

All global variables should be counters

Name: Anonymous 2010-12-26 19:49

All variable conuters should be globals

Name: Anonymous 2010-12-26 20:19

All variable coconuts should be globals.

Name: Anonymous 2010-12-26 20:27

All cars should be cdrs.

Name: Anonymous 2010-12-26 20:56

THIS THREAD HAS BEEN CLOSED AND REPLACED WITH THE FOLLOWING:
    Subject: Replacing all cars with cdrs
    Name:
    Email: mailto:sage
    Message: (let loop ((xs '(1 2 3 4 5)) (r '())) (if (null? xs) r (loop (car xs) (+ (car xs) (car xs)))))
             car: expects argument of type <pair>; given 1

             It doesn't work.

Name: Anonymous 2010-12-26 23:09

>>17
Here's some evil, but non code breaking code:

#.`(cl:defpackage #:inverse-lisp
     (:use #:cl)
     (:shadow #:car #:cdr)
     (:export
      ,@(cl:loop :for sym :being :the :external-symbol :of (find-package :cl)
                 :collect sym)))

(cl:in-package #:inverse-lisp)

(defun car (list) (cl:cdr list))
(defun cdr (list) (cl:car list))

(cl:defpackage #:inverse-lisp-user
  (:use #:inverse-lisp))

(cl:in-package #:inverse-lisp-user)

(car (cons 1 2)) ;=> 2
(cdr (cons 1 2)) ;=> 1


Of course, one could also redefine (this breaks the standard, but would actually work in most implementations) cons/car/cdr such that the positions would be reversed, but you'd just break most of the existing code, not to mention that cons/car/cdr are pretty much always inlined  in any serious implementation (car/cdr being just a simple asm instruction in most cases, while cons just calls a quick allocator and assigns the 2 fields.

Name: Anonymous 2010-12-26 23:23

>>18
#lang racket
(require (prefix-in racket: racket/base))
(provide car cdr)
(define (car l) (racket:cdr l))
(define (cdr l) (racket:car l))

(car (cons 1 2)) ; => 2
(cdr (cons 1 2)) ; => 1


It's Lisp nature to be completely redefineable and extendable, I said "it doesn't work" because of
but you'd just break most of the existing code

Name: Anonymous 2010-12-26 23:25

>>19
When you read that code, please remove the (provide car cdr) line, thanks.

Name: >>18 2010-12-26 23:35

>>19
Well, my code doesn't break any existing code as it just defined a new package which is just like the usual CL one, but with car and cdr having reversed roles. No code is actually affected, but if someone chooses to use this modified implementation, they must use the reversed car/cdr properly if they don't want to break their code.

Name: Anonymous 2010-12-27 20:46

>>17
s/\bcar\b/cdr/g;

Perl wins once again.

Name: Anonymous 2011-02-04 15:23

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