SyntaxHighlighter

вторник, 19 июня 2012 г.

Прекрасный обзор литературы по ФП

Прекрасный обзор литературы по ФП на русском и английском, включает также обзор книг по функциональным языкам программирования: Haskell, Lisp, ML,  Prolog.

http://alexott.net/ru/fp/books/

четверг, 14 июня 2012 г.

Это просто праздник какой-то!

Подробный обзор исходного кода DOOM 3 с картинками и диаграммами http://fabiensanglard.net/doom3/index.php

В качестве бонуса интервью Кармака.

PS: более ранняя  статья того же автора с обзором кода Doom iPhone
http://fabiensanglard.net/doomIphone/index.php

вторник, 5 июня 2012 г.

C++ библиотека базовых классов от Facebook

Компания Facebook  открыла C++11 библиотеку Folly.

https://github.com/facebook/folly

Folly (acronymed loosely after Facebook Open Source Library) is a library of C++11 components designed with practicality and efficiency in mind. It complements (as opposed to competing against) offerings such as Boost and of course std. In fact, we embark on defining our own component only when something we need is either not available, or does not meet the needed performance profile.

Код библиотеки заточен под производительность и эффективное использование памяти, например: есть аналоги std::string и std::vector - fbstring и fbvector.

В авторах числится сам Андрей Александреску.
Код заточен под GCC и новый стандарт C++, есть подозрение, что под VS не соберётся.

FBString

Собственная реализация строк. Особенности реализации:
- для строк меньше 23 символов размещаются на месте, не используя динамической памяти
- для строк от 24 до 255 символов, используется динамически выделяемая память. При копировании строк, копируется и внутреннее хранилище
- для всех остальных строк используется Copy-On-Write стратегия (потокобезопасность гарантируется)
- для выделения памяти используется malloc, allocator-ы не используются
- эффективный алгоритм поиск подстроки (Boyer-Moore algorithm)
 - нулевой символ в конце строке дописывается только при вызове методов c_str() и data(). Этим поведением можно управлять макросами:

FBSTRING_PERVERSE
FBSTRING_CONSERVATIVE


В коде обильно используются assert-ы для проверки различных инвариантов.
Используется вспомогательный внутренний класс для проверки ненарушения методом инварианта класса.
 
  struct Invariant;
  friend struct Invariant;
  struct Invariant {
#ifndef NDEBUG
    explicit Invariant(const basic_fbstring& s) : s_(s) {
      assert(s_.isSane());
    }
    ~Invariant() {
      assert(s_.isSane());
    }
  private:
    const basic_fbstring& s_;
#else
    explicit Invariant(const basic_fbstring&) {}
#endif
    Invariant& operator=(const Invariant&);
  };
 
 Использование (в начале метода):
    Invariant checker(*this);
    (void) checker;
 Таким образом инвариант будет проверен при входе и при выходе из метода.

Вспомогательная функция, для проверки входных параметров
   static void enforce(
      bool condition,
      void (*throw_exc)(const char*),
      const char* msg) {
    if (!condition) throw_exc(msg);
  }

Пример использования:
  void reserve(size_type res_arg = 0) {
    enforce(res_arg <= max_size(), std::__throw_length_error, "");
    store_.reserve(res_arg);
  }

Код интересный и познавательный, содержит различные приёмы и трюки.
Вот пример:

      // Layout is: Char* data_, size_t size_, size_t capacity_
      /*static_*/assert(sizeof(*this) == sizeof(Char*) + 2 * sizeof(size_t));
      /*static_*/assert(sizeof(Char*) == sizeof(size_t));
      // sizeof(size_t) must be a power of 2
      /*static_*/assert((sizeof(size_t) & (sizeof(size_t) - 1)) == 0);

      // If data is aligned, use fast word-wise copying. Otherwise,
      // use conservative memcpy.
      if (reinterpret_cast<size_t>(data) & (sizeof(size_t) - 1)) {
        fbstring_detail::pod_copy(data, data + size, small_);
      } else {
        // Copy one word (64 bits) at a time
        const size_t byteSize = size * sizeof(Char);
        if (byteSize > 2 * sizeof(size_t)) {
          // Copy three words
          ml_.capacity_ = reinterpret_cast<const size_t*>(data)[2];
          copyTwo:
          ml_.size_ = reinterpret_cast<const size_t*>(data)[1];
          copyOne:
          ml_.data_ = *reinterpret_cast<Char**>(const_cast<Char*>(data));
        } else if (byteSize > sizeof(size_t)) {
          // Copy two words
          goto copyTwo;
        } else if (size > 0) {
          // Copy one word
          goto copyOne;
        }
      }

воскресенье, 3 июня 2012 г.

InteLib

InteLib - реализация EDSL лиспа на C++ (oh shi)
http://www.intelib.org/intro.html
LSymbol ISOMORPHIC("ISOMORPHIC");

 static LFunctionalSymbol DEFUN("DEFUN");
 static LFunctionalSymbol COND("COND");
 static LFunctionalSymbol ATOM("ATOM");
 static LFunctionalSymbol AND("AND");
 static LFunctionalSymbol CAR("CAR");
 static LFunctionalSymbol CDR("CDR");

 static LListConstructor L;

 void LispInit_isomorphic() {
   static LSymbol TREE1("TREE1");
   static LSymbol TREE2("TREE2");
   ////////////////////////////////////////////////
   //
   (L|DEFUN, ISOMORPHIC, (L|TREE1, TREE2),
     (L|COND, 
       (L|(L|ATOM, TREE1), (L|ATOM, TREE2)),
       (L|(L|ATOM, TREE2), NIL),
       (L|T, (L|AND,
         (L|ISOMORPHIC, (L|CAR, TREE1), 
                        (L|CAR, TREE2)),
         (L|ISOMORPHIC, (L|CDR, TREE1), 
                        (L|CDR, TREE2))
   )))).Evaluate();
   //
   ////////////////////////////////////////////////
 } 
 //      end of file

Новый проект от Mozilla: Low Level JavaScript

LLJS - это низкоуровневый диалект JavaScript. Язык поддерживает простую типизацию, плоскою модель памяти, структуры. Вообщем, похоже на дитё C и JavaScript-а (ещё напоминает unsafe в C#).

Основная цель проекта - предоставить возможность писать на JavaScript-а эффективный код не страдающий от пауз GC. Код на LLJS преобразуется в обычный JS. Думаю, если реализовать поддержку непосредственно в движке JS (как планирует Google поступить с Dart), может получиться весьма занимательная в плане производительности штука.


Пример:
extern timer;        // Declare timer as an external variable.

let x;               // Declare 'x' as dyn.
let int y;           // Declare 'y' as int.

y = (int)(x);        // Assignment of 'x' to 'y' requires an explicit
                     // cast.

let int z = y + 1;   // Although 'y' is of type int, the binary
                     // expression y + 1 is of type num and
                     // requires an implicit cast.

let uint w = z;      // Unsigned integer types are supported but
                     // are discouraged because JavaScript engines
                     // usually store numbers that are larger than
                     // max signed int in doubles rather than 32-bit
                     // ints.

timer.begin("Empty For loop with signed integers.");
for (let int i = 0; i < 50000000; ++i) { }

timer.begin("Empty For loop with unsigned integers.");
for (let uint i = 0; i < 50000000; ++i) { }

timer.begin("Empty For loop with untyped integers.");
for (let i = 0; i < 50000000; ++i) { }



http://mbebenita.github.com/LLJS/

вторник, 31 января 2012 г.

git добавление нового файла и коммит одной командой

Добавляем alias в .git/config или "C:\Program Files (x86)\Git\etc\gitconfig" для Windows.


[alias]
ac = !git add -A && git commit


Используем:
git ac -m "it's alive!!!"


Подсмотренно здесь http://www.vogella.de/blog/2010/12/25/git-alias-add-commit/