| name | height | weight | smelliness |
|-------+--------+--------+------------|
| alice | 0.6 | 0.4 | 0.8 |
| bob | 0.8 | 0.6 | 0.5 |
| name | height | weight | speed | accuracy | quick thinking |
|-------+--------+--------+-------+----------+----------------|
| bob | 1.0 | 0.5 | 0.3 | 0.1 | 0.2 |
| roy | 0.8 | 0.9 | 0.1 | 0.7 | 0.4 |
| dylan | 0.8 | 0.4 | 0.9 | 0.9 | 0.8 |
| name | typesafety | conciseness | syntax sugar | performance | memory usage | metaprogramming capabilities | total language power as sum of all |
|-------+------------+-------------+--------------+-------------+--------------+------------------------------+------------------------------------|
| lua | 0.0 | 0.6 | 0.1 | 0.4 | 0.8 | 0.0 | 1.9 |
| ruby | 0.0 | 0.9 | 0.8 | 0.1 | 0.2 | 0.5 | 2.5 |
| lisp | 0.0 | 0.6 | 0.2 | 0.3 | 0.5 | 0.6 | 2.2 |
| rust | 1.0 | 0.3 | 0.4 | 1.0 | 1.0 | 0.7 | 4.4 |
| ocaml | 1.0 | 0.8 | 0.2 | 0.9 | 0.8 | 0.3 | 4.0 |
| go | 0.6 | 0.2 | 0.0 | 0.8 | 0.8 | 0.0 | 2.4 |
| java | 0.5 | 0.2 | 0.2 | 0.7 | 0.0 | 0.0 | 1.6 |
| attribute name | importance |
|------------------------------+------------|
| typesafety | 1.0 |
| conciseness | 0.6 |
| syntax sugar | 0.0 |
| performance | 0.5 |
| memory usage | 0.7 |
| metaprogramming capabilities | 0.0 |
| name | typesafety | conciseness | syntax sugar | performance | memory usage | metaprogramming capabilities | total language power as sum of all |
|-------+------------+-------------+--------------+-------------+--------------+------------------------------+------------------------------------|
| lua | 0.0 * 1.0 | 0.6 * 0.6 | 0.1 * 0.0 | 0.4 * 0.5 | 0.8 * 0.7 | 0.0 * 0.0 | 1.12 |
| ruby | 0.0 * 1.0 | 0.9 * 0.6 | 0.8 * 0.0 | 0.1 * 0.5 | 0.2 * 0.7 | 0.5 * 0.0 | 0.73 |
| lisp | 0.0 * 1.0 | 0.6 * 0.6 | 0.2 * 0.0 | 0.3 * 0.5 | 0.5 * 0.7 | 0.6 * 0.0 | 0.86 |
| rust | 1.0 * 1.0 | 0.3 * 0.6 | 0.4 * 0.0 | 1.0 * 0.5 | 1.0 * 0.7 | 0.7 * 0.0 | 2.38 |
| ocaml | 1.0 * 1.0 | 0.8 * 0.6 | 0.2 * 0.0 | 0.9 * 0.5 | 0.8 * 0.7 | 0.3 * 0.0 | 2.49 |
| go | 0.6 * 1.0 | 0.2 * 0.6 | 0.0 * 0.0 | 0.8 * 0.5 | 0.8 * 0.7 | 0.0 * 0.0 | 1.68 |
| java | 0.5 * 1.0 | 0.2 * 0.6 | 0.2 * 0.0 | 0.7 * 0.5 | 0.0 * 0.7 | 0.0 * 0.0 | 0.97 |
QuoteFor a wide range of applications, neither ClickHouse nor Druid or Pinot are obvious winners. First and foremost, I recommend to take into account, the source code of which system your are able to understand, fix bugs, add features, etc. The section "On Performance Comparisons and Choice of the System" discusses this more.
interface PriceApi {
double getPrice();
}
class ExchangeA implements PriceApi {
double getPrice() {
...
return thePrice;
}
}
...
double queryPrice(PriceApi api) {
return api.getPrice();
}
interface PriceApi {
void initSession();
double getPrice();
}
class ExchangeA implements PriceApi {
void initSession() {}
double getPrice() {
...
return thePrice;
}
}
class ExchangeB implements PriceApi {
void initSession() {
// do some magicka to initiate the session
...
}
double getPrice() {
...
return thePrice;
}
}
...
double queryPrice(PriceApi api) {
api.initSession();
return api.getPrice();
}
type exchange =
| ExchangeA
| ExchangeB
let query_price =
function
| ExchangeA -> (
exchange_a_get_price ()
)
| ExchangeB -> (
exchange_b_init_session ();
exchange_b_get_price ()
)
let res = execute_write ~params:[|string_of_int voting_id|] pg "
UPDATE voting_session
SET signatures_count = signatures_count + 1
WHERE voting_id = $1
AND NOT is_scheduled
AND NOW() < petition_deadline
" in
let db_queries = [
...
mk_db_mutator
FtVoting
"increment_voting_signatures_count"
{|
-- voting_id:15
UPDATE voting_session
SET signatures_count = signatures_count + 1
WHERE voting_id = <voting_id:int>
AND NOT is_scheduled
AND NOW() < petition_deadline
|};
...
]
let dbm_increment_voting_signatures_count (pg: Postgresql.connection) ~(voting_id: int) =
incr dbm_increment_voting_signatures_count_init_count;
let timestamp = now () in
send_db_query_record ~timestamp ~query_label:"dbm_increment_voting_signatures_count" ~duration:(-1.0) ~rows_affected:0 ~rows_returned:(-1) ~arguments_keys:["voting_id"] ~arguments_values
:[string_of_int voting_id];
let res = execute_write ~params:[|string_of_int voting_id|] pg "
UPDATE voting_session
SET signatures_count = signatures_count + 1
WHERE voting_id = $1
AND NOT is_scheduled
AND NOW() < petition_deadline
" in
let duration = now () -. timestamp in
let rows_affected = int_of_string_opt res.result#cmd_tuples |> Option.value ~default:(-1) in
incr dbm_increment_voting_signatures_count_success_count;
incr_float dbm_increment_voting_signatures_count_duration_sum duration;
send_db_query_record ~timestamp ~query_label:"dbm_increment_voting_signatures_count" ~duration ~rows_affected ~rows_returned:0 ~arguments_keys:["voting_id"] ~arguments_values:[string_of_int voting_id];
res
let db_tables = [
...
mk_db_table
11
"chat_message_likes"
[
mk_field 1 "message_id" Int ~index:true;
mk_field 2 "user_id" Int ~index:true;
mk_field 3 "time_liked" Timestamp ~default:"CURRENT_TIMESTAMP" ~index:true;
]
~uniq_constraints:["message_id"; "user_id"]
~test_data:[
["112"; "10"; "NOW()"];
["113"; "12"; "NOW()"];
]
;
...
]
let rest_endpoints = [
...
mk_rest_endpoint
FtForum
"/api/post_to_chat_room"
LoggedInUser
(CustomAction "post_to_chat");
...
]
let custom_actions = [
...
mk_custom_action
FtForum
~return_type:"post_to_chat_return_result"
"post_to_chat"
[
"chat_room_id", Int;
"contents", String;
];
...
]
type post_to_chat_return_result =
| CAR_PostMsg_MessageTooLong
| CAR_PostMsg_EmptyMessage
| CAR_PostMsg_UserDoesntBelongToRoom
| CAR_PostMsg_Ok
[@@deriving yojson]
rest_post_post_to_chat { chat_room_id = chat_room.room_id; contents = contents } (fun res ->
match res with
| CAR_PostMsg_Ok -> (
materialize_toast "Hoooray, posted!"
)
| CAR_PostMsg_MessageTooLong -> (
materialize_toast "Message to long"
)
| CAR_PostMsg_EmptyMessage -> (
materialize_toast "Message empty"
)
| CAR_PostMsg_UserDoesntBelongToRoom -> (
materialize_toast "You do not belong to this chat room"
)
)
post "/api/post_to_chat_room" begin fun req ->
wauth_succ "backend_rest_ca_post_to_chat" req (fun session ->
App.string_of_body_exn req |> Lwt.map (fun json ->
match Yojson.Safe.from_string json |> gen_type_7557852441389680360_of_yojson with
| Ok args -> (
let with_connection = with_connection ~ray_id:(get_ray_id_from_request req) in
let api = mk_custom_action_auth_api "post_to_chat" with_connection session req.request in
let result = ca_post_to_chat api (args.chat_room_id) (args.contents) in
result |> post_to_chat_return_result_to_yojson |> Yojson.Safe.to_string |> respond_json_str_lwt
)
| Error err -> respond_json_str_lwt "PHEIL"
)
)
end;
let ca_post_to_chat ~(api: custom_action_auth_api) ~(chat_room_id: int) ~(contents: string) =
if String.length contents > 1000 then (
CAR_PostMsg_MessageTooLong
) else if String.is_empty contents then (
CAR_PostMsg_EmptyMessage
) else (
with_connection "post_message_to_chat" (fun c ->
let res = dbq_does_user_belong_to_chat_room c
~user_id:api.session_data.user_id ~room_id:chat_room_id in
if res.(0).user_belongs > 0 then (
dbm_post_to_chat_room c
~user_id:api.session_data.user_id
~chat_room_id ~contents |> ensure_pg_ok;
CAR_PostMsg_Ok
) else (
CAR_PostMsg_UserDoesntBelongToRoom
)
)
)
let rest_post_post_to_chat (args: gen_type_7557852441389680360) with_result =
let url_var = Printf.sprintf "/api/post_to_chat_room" in
let body = gen_type_7557852441389680360_to_yojson args |> Yojson.Safe.to_string in
post_ajax_url_json_wcallback url_var "frontend_ca_post_to_chat" body (fun str_res ->
Yojson.Safe.from_string str_res |> post_to_chat_return_result_of_yojson |>
function
| Ok result -> (
with_result result
)
| Error err -> (
print_endline "Cannot deserialize custom action"
)
)
let templates = [
...
mk_template "some_template_ini" {|
ip_address = <the_ip:string>
open_port = <port:int>
<iterate peers { peer_port: int, peer_ip: string }
connection = <peer_ip>:<peer_port>
<iterate end>
|};
...
];
let template_string = tplt_some_template_ini ~the_ip:"127.0.0.1" ~port:8080 ~peers:[{ peer_port = 1234; peer_ip = "1.1.1.1" }] in
...
let x = 7
let square arg = arg * arg
List.map [1; 2; 3] ~f:(fun i -> i * i) ;; will yield [1; 4; 9]
fn square(num: i64) -> i64 {
num * num
}
f, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}