2015-03-17

Планируя собрать проект на свежеустановленной в виртуалку убунте, набрал

svn clone http://...

"git stat", кстати, тоже частый гость.

немного за rust

  1. Получил прекрасное сообщение об ошибке:
     error: mismatched types:
     expected `&fn(i32, i32) -> i32 {foo::plus}`,
        found `&fn(i32, i32) -> i32 {foo::minus}`
    
     let v: &[&Fn(i32, i32) -> i32] = [&plus, &minus];
    
    На самом деле, там проблема в другом месте -- массив не приведен к срезу ( забыл & перед [), что видно из след. сообщения об ошибке. 
  2. Из примера использования биндингов к Qt
    QString::new7("Cannot load %1.").arg12(&fileName, 0, &QChar::new9(' ' as i8))
    Разные версии функций Qt, отличающиеся типов аргуменов, при генерации биндингов получили индексы. Перегрузка функции по типу аргументов не то чтобы невозможна, но требует некоторой работы -- нужен параметризируемый (generic) трейт ("интерфейс",  аналог class из Хаскеля или protocol из Свифта):
    trait Overload<X> {
     fn call_with(self, arg: X) -> ();
    }
    
    struct Foo;
    
    impl Overload<u8> for Foo {
     fn call_with(self, arg: u8) {  }
    }
    
    impl Overload<i32> for Foo {
     fn call_with(self, arg: i32) {  }
    }
    
    

2015-03-05

Из анонса новой CRT в Visual Studio

...
The "best" example of this maintainability problem could be found in the old implementation of the printf family of functions. The CRT provides 142 different variations of printf, but most of the behavior is the same for all of the functions, so there are a set of common implementation functions that do the bulk of the work. These common implementation functions were all defined in output.c in the CRT sources(1). This 2,696 line file had 223 conditionally compiled regions of code (#ifdef, #else, etc.), over half of which were in a single 1,400 line function. This file was compiled 12 different ways to generate all of the common implementation functions. 
...
We have converted most of the CRT sources to compile as C++, enabling us to replace many ugly C idioms with simpler and more advanced C++ constructs. The publicly callable functions are still declared as C functions, of course (extern "C" in C++), so they can still be called from C. But internally we now take full advantage of the C++ language and its many useful features.
...
Before this refactoring, the sprintf functions, which write formatted data to a character buffer, were implemented by wrapping the result buffer in a temporary FILE object and then deferring to the equivalent fprintf function. 

2014-12-25

что мертво -- умереть не может

На дворе без малого 2015 год, а люди все еще используют VC6 (прислали сделанное тестовое).

2014-12-04

Callbacks vs promises

Добавил в текущий проект промисы. Для сравнения

До:
-(void) p_pluckHamsSinceLastPluckWithCompletion:(BarPluckHamsCompletion) completion
{
  NSDate * date = [NSUserDefaults standardUserDefaults].lastPluckDate;

  XXXHamPlucker plucker = ^(XXXPluckSession * session, XXXFoo *foo, XXXPluckConsumer consumer) {
    [session searchBoosSinceDate:date withFoo:foo completion:^(NSError *error, NSIndexSet * boos) {
      if (error)
        return consumer(error, nil);
      [Bar filterBoos:boos withFoo:foo completion:^(NSIndexSet *boos) {
        [session pluckHamsWithBoos:boos withFoo:foo completion:^(NSError * error, NSArray * hams) {
          if (error)
            return consumer(error, nil);
          [Bar filterHams:hams inFoo:foo completion:^(NSArray *hams) {
            consumer(nil, hams);
          }];
        }];
      }];
    }];
  };

  [self p_pluckHamsUsingPlucker:plucker completionHandler:completion];
}

После
-(XXXPromise *) p_pluckHamsSinceLastPluck {
  NSDate * date = [NSUserDefaults standardUserDefaults].lastPluckDate;

  XXXHamPlucker plucker = ^(XXXPluckSession * session, XXXFoo * foo) {
    XXXPromise * promise = [session searchBoosSinceDate:date withFoo:foo];
    return promise.thenPromise(^(NSIndexSet * boos){
      return [Bar filterBoos:boos withFoo:foo];
    }).thenPromise(^(NSIndexSet * boos){
      return [session pluckHamsWithBoos:boos withFoo:foo];
    }).thenPromise(^(NSArray * hams) {
      return [Bar filterHams:hams withFoo:foo];
    });
  };

  return [self p_pluckHamsUsing:plucker];
}

Промисы свои, написал часа за 3-4. Смотрел RXPromise и PromiseKit, но они не умеют то, что мне нужно.

2014-07-22

some fancy swift errors

5> [1,2,3].map { $1 * 10 }
<repl>:5:9: error: type '(($T7, ($T7, $T8) -> ($T7, $T8) -> $T6) -> ($T7, ($T7, $T8) -> $T6) -> $T6, (($T7, $T8) -> ($T7, $T8) -> $T6, $T8) -> (($T7, $T8) -> $T6, $T8) -> $T6)' does not conform to protocol 'IntegerLiteralConvertible'
6> let x = [1,2,3]
x: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
7> x.map { $1 * 10 }
<REPL>:8:7: error: 'Int' is not a subtype of '(($T5, ($T5, $T6) -> ($T5, $T6) -> $T4) -> ($T5, ($T5, $T6) -> $T4) -> $T4, (($T5, $T6) -> ($T5, $T6) -> $T4, $T6) -> (($T5, $T6) -> $T4, $T6) -> $T4)'
x.map { $1 }
и эти люди ругают С++ за сообщения об ошибках...
PS. Если что, правильный код --  x.map { $0 * 10 }

2014-05-15

Что может быть проще емейла...

сотрудник:
тебе не приходилось на плюсах делать проверку на типа валидный email
­
bitfield:
в инете есть страшные регекспы
­
сотрудник:
я их боюсь
думал может что готовое есть
­
bitfield:
я б не парился, проверял на x@y.z where x,y,z in [a-zA-Z0-9.+-]
­
сотрудник:
так и сделаю
­
bitfield:
вообще-то, там все грустно и запущено.
­
сотрудник:
да уж, я читал про 1000 символьный регексп на перле
­
bitfield:
тесты к одному чекеру

[("\"Abc\\@def\"@example.com",True),
("\"Fred Bloggs\"@example.com",True),
("\"Joe\\Blow\"@example.com",True),
("\"Abc@def\"@example.com",True),
("customer/department=shipping@example.com",True),
("$A12345@example.com",True),
("!def!xyz%abc@example.com",True),
("_somename@example.com",True),
("NotAnEmail",False),
("@NotAnEmail",False),
("\"test\\\\blah\"@example.com",True),
("\"test\\blah\"@example.com",True),
-- # Phil gets false for this, which I think is wrong
-- # (Dominic Sayers notes the same at the end of the comment thread)
("\"test\\\rblah\"@example.com",True),
("\"test\rblah\"@example.com",False),
("\"test\\\"blah\"@example.com",True),
("\"test\"blah\"@example.com",False),
("customer/department@example.com",True),
("$A12345@example.com",True),
("!def!xyz%abc@example.com",True),
("_Yosemite.Sam@example.com",True),
("~@example.com",True),
(".wooly@example.com",False),
("wo..oly@example.com",False),
("pootietang.@example.com",False),
(".@example.com",False),
("\"Austin@Powers\"@example.com",True),
("Ima.Fool@example.com",True),
("\"Ima.Fool\"@example.com",False),
("\"Ima Fool\"@example.com",False),
("Ima Fool@example.com",False)]
­
сотрудник:
ааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа!!!!!!!!!!!!!!!!!!!!!!!!!!
­
bitfield:
самая жесть, в имейле могут быть круглые скобки, и они должны совпадать
isValid "((lol)porges(()comme(nests)nt())@example.com" == False
isValid "((lol))porges(()comme(nests)nt())@example.com" == True
isValid "\"s\\\0\"@example.com" == True
-- # "s\NUL"@example.com, where NUL is actually the
-- # null character! Yep, can't strlen() on email addresses...
­
сотрудник:
чудесно
­
bitfield:
да я сам в ах^Wвосхищении