LINUX.ORG.RU

Сообщения korvin_

 

Почему в Ocaml такое неочевидное поведение вложенных блоков?

Например:

let println x = print_int x ; print_newline ()
 
let proc0a () =
	print_endline "proc0a" ;
	let x = 1
	in
		println x ;
		let x = 2
		in
			println x ;
		println x
 
let proc0b () =
	print_endline "proc0b" ;
	let x = 1
	in begin
		println x ;
		let x = 2
		in begin
			println x
		end ;
		println x
	end
 
let proc0c () =
	print_endline "proc0c" ;
	let x = 1
	in (
		println x ;
		let x = 2
		in (
			println x
		) ;
		println x
	)
 
let proc1 () =
	print_endline "proc1" ;
	let x = 1
	in
		println x ;
		( let x = 2
		in
			println x
		) ;
		println x
 
let proc p =
	p () ;
	print_newline ()
 
let _ = List.iter proc [ proc0a; proc0b; proc0c; proc1 ]

получаем:

proc0a
1
2
2

proc0b
1
2
2

proc0c
1
2
2

proc1
1
2
1

Я ожидал от proc0(a|b|c) поведения аналогичного proc1, но нет.

В SML поведение соответствует ожиданиям:

fun println x = print (Int.toString x ^ "\n")
 
fun proc0 () = (
	print "proc0\n" ;
	let val x = 1
	in
		println x ;
		let val x = 2
		in
			println x
		end ;
		println x
	end
)
 
val _ = proc0 ()

=>

proc0c
1
2
1

Как и в Haskell:

proc0a = do
	putStrLn "proc0a"
	let x = 1 in do
		print x
		let x = 2 in do
			print x
		print x
 
proc0b = do {
	putStrLn "proc0b" ;
	let x = 1 in do {
		print x ;
		let x = 2 in do {
			print x
		} ;
		print x
	}
}
 
proc1a = do
	putStrLn "proc1a"
	let x = 1 in do
		print x
		let x = 2 in do
			print x
			print x
 
proc1b = do {
	putStrLn "proc1b" ;
	let x = 1 in do {
		print x ;
		let x = 2 in do {
			print x ;
			print x
		}
	}
}
 
main = mapM_ (\p -> p >> putStrLn "") [ proc0a, proc0b, proc1a, proc1b ]

=>

proc0a
1
2
1

proc0b
1
2
1

proc1a
1
2
2

proc1b
1
2
2

Как и в любом другом языке (может, в F#, как, во-многом, наследнике Ocaml, поведение аналогично предку? Лень проверять).

Так почему разработчики Ocaml сделали так, а не как у людей?

 ,

korvin_
()

DDL-запрос и select в одном Statement

Есть пара запросов, примерно таких:

drop table if exists temp_table ;
select * into temp table temp_table
	from real_table ;
select * from temp_table ;
create extension if exists dblink ;
select * from some_table ;

и соответственно примерно такой код:

try (Statement stmt = dataSource.getConnection().createStatement()) {
	boolean results = stmt.execute(request.query);
	while (results) {
		try (ResultSet rs = stmt.getResultSet()) {
			// process
		}
		results = stmt.getMoreResults();
	}
}

В результате Statement не возвращает ни одного ResultSet'а, хотя, если в запросе просто несколько select'ов, типа

select * from some_table ;
select * from another_table ;

Вопрос: почему statement не возвращает ResultSet('ы) и можно ли как-то эти запросы выполнить, чтобы возвращал?

// PostgreSQL 9.5

 ,

korvin_
()

Особенности системы типов и расширения GHC

Вероятно, на это уже давно есть ответ, но я даже не знаю как правильно загуглить.

Например, такой код:

import Data.List
 
main = print $ nub []

не компилируется. Причины понятны, решение (указать тип списка явно с любым типом элементов, для которого реализован, в данном случае, Eq) тоже.

Но это как-то криво, поэтому прошу подсказать, как можно реализовать (типизировать) nub (и любую другую подобную функцию), которая принимала бы пустой список произвольного типа, несмотря на то, что требует список элементов какого-то типа определённого тайпкласса. У length, например, проблем нет, т.к. она не ограничивает тип элементов тайпклассом.

P.S. Typed Racket, например, такое легко позволяет (хотя автоматически вывести тип для nub не может):

(: nub (All (a) (-> (Listof a) Any)))
(define (nub xs)
  (match xs
    ((list) #t)
    ((cons x xs) (and (not (member x xs))
                      (nub xs)))))

(print (nub '())) ;=> #t

Тут, правда, и тайпклассов нет. =)

Предполагаю, что языки с зависимыми типами также такой проблемы не имеют.

 , не anonimus,

korvin_
()

Воспроизведение видео по сети

Ситуация следующая: имеется слабый нетбук, 720p/1080p видеофайлы воспроизводить не способен, однако можно транслировать видеопоток с десктопа по сети с помощью VLC, но управлять этим потоком, понятное дело, нельзя.

Нагуглил аббревиатуру DLNA, немного почитал, не совсем понял, то ли это, что мне нужно и, если то, в какой комбинации на каком устройстве мне его «разворачивать» (там сервер, плеер, контроллер). Однако вроде как обработку файла (декодировка) производит плеер (т.е. клиент).

Собственно нужен видеосервер, предоставляющий клиенту возможности управления (список файлов, выбор файла для воспроизведения, управление потоком), но выполняющий обработку видео самостоятельно, а клиенту отдающий только картинку. Подскажите в какую сторону гуглить?

 , ,

korvin_
()

Проблема хрупкого базового класса

Сегодня один индивидуум рассказал мне об одной фундаментальной проблеме ООП и я нифига не понял.

Есть такой пример: http://stackoverflow.com/questions/2921397/what-is-the-fragile-base-class-pro... Здесь имеется в виду, что при вызове Sub::m() x увеличится на единицу дважды? Но чем это отличается от любого другого языка? (я опущу разделение на h и cpp)

namespace Base {
  int x;
  void m() { x++; }
  void n() { x++; m(); }
}
#include "base.h"
namespace Sub {
  void m() { Base::n(); }
}

upd: простой тест показал, что проблема не в инкрементах (а ведь я хотел написать про рекурсию, но комметарий defect меня смутил, да и я подумал, что джава не настолько хренова, чтобы вызывать неабстрактные методы вот так вот).

Впрочем даже в этом случае, что мешает в любом языке так запортачить с поздним связыванием и рекурсией?

 ,

korvin_
()

Динамическое локальное переопределение методов класса

Здравствуйте. Подскажите в каких ЯП присутствует возможность динамически локально переопределять методы класса?

Что-то вроде такого(слово public не писал просто, чтобы не мешалось, а так методы публичные):

class A {
    int id() {
        return 0;
    }
}

class App {

    static A make() {
        return new A();
    }
    
    static void print(A a) {
        System.out.println(a.id());
    }
    
    class B overrides A { // класс B равнозначен классу A,
        int id() {        // но переопределяет метод id()
            return 1;
        }
    }
    
    static void forObject(A a) {

        print(a); => 0
        print(a as B); // => 1
        print(a as A {
            int id() {
                return 2;
            }
        }); // => 2
        print(a); => 0
    }
    
    static void forClass(A a) {

        print(a); => 0
        override A as B;
        print(a); // => 1
        override A {
            int id() {
                return 2;
            }
        }
        print(a); // => 2
    }
    
    static void main(String[] args) {
    
        A a = make();
        print(a); => 0
        forObject(a);
        forClass(a);
        print(a); => 0
    }
}

Или хотя бы часть из того, что есть в примере.

P.S. Классово/методовое ООП не обязательно, процедуры или функции тоже подойдут.

P.P.S. Кроме CL =)

korvin_
()

[тип][ооп][интерфейс]Почему считается, что тип == интерфейс?

Цитата из TAPL (глава 18.1):

Подтипы. Тип объекта — его интерфейс (interface), — это просто множество имен и типов его операций. Внутреннее представление объекта не фигурирует в его типе, поскольку оно не влияет на набор действий, которые могут быть проделаны над объектом.

Почему считается, что тип объекта — его интерфейс? Ведь возможна ситуация, когда два класса реализуют один и тот же интерфейс, но эти реализации обладают совершенно разным поведением по смыслу.

 ,

korvin_
()

RSS подписка на новые темы